* [PATCH v4 00/18] Imagination BXS-4-64 MC1 GPU support
@ 2025-03-20 11:32 Matt Coster
2025-03-20 11:32 ` [PATCH v4 01/18] dt-bindings: gpu: img: Future-proofing enhancements Matt Coster
` (17 more replies)
0 siblings, 18 replies; 21+ messages in thread
From: Matt Coster @ 2025-03-20 11:32 UTC (permalink / raw)
To: Frank Binns, Matt Coster, David Airlie, Simona Vetter,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Nishanth Menon,
Vignesh Raghavendra, Tero Kristo
Cc: dri-devel, devicetree, linux-kernel, linux-arm-kernel,
Randolph Sapp, Darren Etheridge, Michal Wilczynski, Alessio Belle,
Alexandru Dadu, Sarah Walker
This GPU is found in the TI AM68 family of SoCs, with initial support
added to the k3-j721s2 devicetree and tested on a TI SK-AM68 board.
A suitable firmware binary can currently be found in the IMG
linux-firmware repository[1] as powervr/rogue_36.53.104.796_v1.fw.
No new UAPI will be necessary for this platform as it is sufficiently
similar to the already supported AXE-1-16M.
UMD support is close to being complete. We're now able to pass >92% of
Vulkan conformance on our Mesa development branch. The compiler has been
undergoing a significant rework needed to accomodate the BXS-4-64, as
well as to make it more flexible to support additional Rogue GPUs going
forward. The first part of this rework landed in Mesa in [2], and the
next chunk is currently in review in [3].
There are several dt-bindings changes at the beginning of this series.
We expect the result to be versatile enough to handle all Imagination
Rogue GPUs while being a strong foundation to build bindings for the
newer Volcanic architecture (for which we're currently developing
support).
The DTS changes at the end of the series are marked [DO NOT MERGE]. Once
the series is reviewed, we will request these be taken through the
relevant tree.
This version of the series depends on a patch[4] which exists in
drm-misc-fixes, but has not yet made it back to drm-misc-next (the
target of this series). That patch adds the function pvr_vm_unmap_obj()
which is used in patch 14 ("drm/imagination: Add RISC-V firmware
processor support").
[1]: https://gitlab.freedesktop.org/imagination/linux-firmware/-/tree/powervr
[2]: https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/32258
[3]: https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/33998
[4]: https://lore.kernel.org/r/20250226-hold-drm_gem_gpuva-lock-for-unmap-v2-1-3fdacded227f@imgtec.com
---
Changes in v4:
- Update status of UMD support (cover)
- Fix backwards compatibility of new compatible strings (P1)
- Fix power-domains property constraints (P1/P2)
- Fix power-domain-names property constraints (P2)
- Only invoke pvr_device_safety_irq_clear() if has_safety_events is set
(P7)
- Use pvr_vm_unmap_obj() in pvr_riscv_vm_unmap() (P14)
- Fix formatting of pvr_riscv_fw_process() signature (P14)
- Link to v3: https://lore.kernel.org/r/20250310-sets-bxs-4-64-patch-v1-v3-0-143b3dbef02f@imgtec.com
Changes in v3:
- Reorder some patches to ensure the proper sequencing
- Update status of UMD support (cover)
- Don't use more specific compatible strings when not required (P1)
- Avoid ABI break by limiting new required properties to new compatible
strings (P2)
- Move power domain changes to the patch in which they're used (P2/P5)
- Update register definitions (P3) [Thanks, Alessio!]
- Don't use more specific compatible strings when not required (P4)
- Enhanced commit messages (P4)
- Remove unnecessary example (P5)
- Add proper fixes for threaded IRQs (P6) [Thanks, Alessio!]
- Include fix for a separate IRQ issue (P7) [Thanks, Alessio!]
- Don't enable firmware debug module (was P13 in v2, also in P14)
- Change from a workaround to a regular codepath (P15)
- Drop platform overrides framework (was P18 in v2, also in P16)
- Mark DTS changes [DO NOT MERGE] (P17/P18)
- Link to v2: https://lore.kernel.org/r/20241118-sets-bxs-4-64-patch-v1-v2-0-3fd45d9fb0cf@imgtec.com
Changes in v2:
- Clarified justification for compatible strings (P1)
- Simplified clocks constraints (P2)
- Simplified power-domains constraints (P3/P4)
- Use normal reg syntax for 64-bit values (P8/P21)
- Link to v1: https://lore.kernel.org/r/20241105-sets-bxs-4-64-patch-v1-v1-0-4ed30e865892@imgtec.com
---
Alessio Belle (3):
drm/imagination: Update register defs for newer GPUs
drm/imagination: Mask GPU IRQs in threaded handler
drm/imagination: Handle Rogue safety event IRQs
Matt Coster (14):
dt-bindings: gpu: img: Future-proofing enhancements
dt-bindings: gpu: img: Add BXS-4-64 devicetree bindings
drm/imagination: Use new generic compatible string
drm/imagination: Add power domain control
drm/imagination: Remove firmware enable_reg
drm/imagination: Rename event_mask -> status_mask
drm/imagination: Make has_fixed_data_addr a value
drm/imagination: Use a lookup table for fw defs
drm/imagination: Use callbacks for fw irq handling
drm/imagination: Move ELF fw utils to common file
drm/imagination: Use cached memory with dma_coherent
drm/imagination: Add support for TI AM68 GPU
[DO NOT MERGE] arm64: dts: ti: k3-am62: New GPU binding details
[DO NOT MERGE] arm64: dts: ti: k3-j721s2: Add GPU node
Sarah Walker (1):
drm/imagination: Add RISC-V firmware processor support
.../devicetree/bindings/gpu/img,powervr-rogue.yaml | 81 +++++++++-
arch/arm64/boot/dts/ti/k3-am62-main.dtsi | 4 +-
arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi | 12 ++
drivers/gpu/drm/imagination/Makefile | 2 +
drivers/gpu/drm/imagination/pvr_device.c | 126 ++++++++++++++--
drivers/gpu/drm/imagination/pvr_device.h | 31 +++-
drivers/gpu/drm/imagination/pvr_drv.c | 16 ++
drivers/gpu/drm/imagination/pvr_fw.c | 28 +++-
drivers/gpu/drm/imagination/pvr_fw.h | 85 +++++------
drivers/gpu/drm/imagination/pvr_fw_meta.c | 23 +--
drivers/gpu/drm/imagination/pvr_fw_mips.c | 82 ++--------
drivers/gpu/drm/imagination/pvr_fw_riscv.c | 165 +++++++++++++++++++++
drivers/gpu/drm/imagination/pvr_fw_startstop.c | 17 +++
drivers/gpu/drm/imagination/pvr_fw_util.c | 67 +++++++++
drivers/gpu/drm/imagination/pvr_gem.c | 10 +-
drivers/gpu/drm/imagination/pvr_gem.h | 6 +-
drivers/gpu/drm/imagination/pvr_mmu.c | 8 +-
drivers/gpu/drm/imagination/pvr_power.c | 114 ++++++++++++++
drivers/gpu/drm/imagination/pvr_power.h | 3 +
drivers/gpu/drm/imagination/pvr_rogue_cr_defs.h | 153 ++++++++++++++++---
drivers/gpu/drm/imagination/pvr_rogue_riscv.h | 41 +++++
21 files changed, 896 insertions(+), 178 deletions(-)
---
base-commit: d034e6f7ea8ddc866d4ac59c104e18675b13975b
change-id: 20241021-sets-bxs-4-64-patch-v1-44cdf9cc555f
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH v4 01/18] dt-bindings: gpu: img: Future-proofing enhancements
2025-03-20 11:32 [PATCH v4 00/18] Imagination BXS-4-64 MC1 GPU support Matt Coster
@ 2025-03-20 11:32 ` Matt Coster
2025-03-20 20:32 ` Rob Herring (Arm)
2025-03-20 11:32 ` [PATCH v4 02/18] dt-bindings: gpu: img: Add BXS-4-64 devicetree bindings Matt Coster
` (16 subsequent siblings)
17 siblings, 1 reply; 21+ messages in thread
From: Matt Coster @ 2025-03-20 11:32 UTC (permalink / raw)
To: Frank Binns, Matt Coster, David Airlie, Simona Vetter,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Nishanth Menon,
Vignesh Raghavendra, Tero Kristo
Cc: dri-devel, devicetree, linux-kernel, linux-arm-kernel,
Randolph Sapp, Darren Etheridge, Michal Wilczynski, Alessio Belle,
Alexandru Dadu
The first compatible strings added for the AXE-1-16M are not sufficient to
accurately describe all the IMG Rogue GPUs. The current "img,img-axe"
string refers to the entire family of Series AXE GPUs, but this is
primarily a marketing term and does not denote a level of hardware
similarity any greater than just "Rogue".
The more specific "img,img-axe-1-16m" string refers to individual AXE-1-16M
GPU. For example, unlike the rest of the Series AXE GPUs, the AXE-1-16M
only uses a single power domain.
The situation is actually slightly worse than described in the first
paragraph, since many "series" (such as Series BXS found in the TI AM68
among others and added later in this series) contain cores with both Rogue
and Volcanic architectures.
Besides attempting to move away from vague groupings defined only
by marketing terms, we want to draw a line between properties inherent to
the IP core and choices made by the silicon vendor at integration time.
For instance, the number of power domains is a property of the IP core,
whereas the decision to use one or multiple clocks is a vendor one.
In the original compatible strings, we must use "ti,am62-gpu" to constrain
both of these properties since the number of power domains cannot be fixed
for "img,img-axe".
Work is currently underway to add support for volcanic-based Imagination
GPUs, for which bindings will be added in "img,powervr-volcanic.yaml".
As alluded to previously, the split between rogue and volcanic cores is
non-obvious at times, so add a generic top-level "img,img-rogue" compatible
string here to allow for simpler differentiation in devicetrees without
referring back to the bindings.
The currently supported GPU (AXE-1-16M) only requires a single power
domain. Subsequent patches will add support for BXS-4-64 MC1, which has
two power domains. Add infrastructure now to allow for this.
Also allow the dma-coherent property to be added to IMG Rogue GPUs, which
are DMA devices. The decision for coherency is made at integration time and
this property should be applied wherever it accurately describes the
vendor integration.
Note that the new required properties for power domains are conditional on
the new base compatible string to avoid an ABI break.
Signed-off-by: Matt Coster <matt.coster@imgtec.com>
---
Changes in v4:
- Add img,img-rogue back to ti,am62-gpu compatible strings to allow
compatibility with older kernels
- Revert change to power-domains property and add proper constraint
- Link to v3: https://lore.kernel.org/r/20250310-sets-bxs-4-64-patch-v1-v3-1-143b3dbef02f@imgtec.com
Changes in v3:
- Remove unnecessary example
- Remove second power domain details, add these where they're used instead
- Avoid ABI breaks by limiting new required properties to new compatible
strings and making all binding changes in a single patch.
- Links to v2:
https://lore.kernel.org/r/20241118-sets-bxs-4-64-patch-v1-v2-1-3fd45d9fb0cf@imgtec.com
https://lore.kernel.org/r/20241118-sets-bxs-4-64-patch-v1-v2-3-3fd45d9fb0cf@imgtec.com
https://lore.kernel.org/r/20241118-sets-bxs-4-64-patch-v1-v2-4-3fd45d9fb0cf@imgtec.com
---
.../devicetree/bindings/gpu/img,powervr-rogue.yaml | 44 +++++++++++++++++++---
1 file changed, 39 insertions(+), 5 deletions(-)
diff --git a/Documentation/devicetree/bindings/gpu/img,powervr-rogue.yaml b/Documentation/devicetree/bindings/gpu/img,powervr-rogue.yaml
index 256e252f8087fa0d6081f771a01601d34b66fe19..2a692feb5bcd526788117fce7934eef9521b364d 100644
--- a/Documentation/devicetree/bindings/gpu/img,powervr-rogue.yaml
+++ b/Documentation/devicetree/bindings/gpu/img,powervr-rogue.yaml
@@ -12,10 +12,23 @@ maintainers:
properties:
compatible:
- items:
- - enum:
- - ti,am62-gpu
- - const: img,img-axe # IMG AXE GPU model/revision is fully discoverable
+ oneOf:
+ - items:
+ - enum:
+ - ti,am62-gpu
+ - const: img,img-axe-1-16m
+ # This deprecated element must be kept around to allow old kernels to
+ # work with newer dts.
+ - const: img,img-axe
+ - const: img,img-rogue
+
+ # This legacy combination of compatible strings was introduced early on
+ # before the more specific GPU identifiers were used.
+ - items:
+ - enum:
+ - ti,am62-gpu
+ - const: img,img-axe
+ deprecated: true
reg:
maxItems: 1
@@ -35,8 +48,15 @@ properties:
maxItems: 1
power-domains:
+ minItems: 1
maxItems: 1
+ power-domain-names:
+ items:
+ - const: a
+
+ dma-coherent: true
+
required:
- compatible
- reg
@@ -47,6 +67,18 @@ required:
additionalProperties: false
allOf:
+ # Constraints added alongside the new compatible strings that would otherwise
+ # create an ABI break.
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: img,img-rogue
+ then:
+ required:
+ - power-domains
+ - power-domain-names
+
- if:
properties:
compatible:
@@ -64,10 +96,12 @@ examples:
#include <dt-bindings/soc/ti,sci_pm_domain.h>
gpu@fd00000 {
- compatible = "ti,am62-gpu", "img,img-axe";
+ compatible = "ti,am62-gpu", "img,img-axe-1-16m", "img,img-axe",
+ "img,img-rogue";
reg = <0x0fd00000 0x20000>;
clocks = <&k3_clks 187 0>;
clock-names = "core";
interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
power-domains = <&k3_pds 187 TI_SCI_PD_EXCLUSIVE>;
+ power-domain-names = "a";
};
--
2.49.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v4 02/18] dt-bindings: gpu: img: Add BXS-4-64 devicetree bindings
2025-03-20 11:32 [PATCH v4 00/18] Imagination BXS-4-64 MC1 GPU support Matt Coster
2025-03-20 11:32 ` [PATCH v4 01/18] dt-bindings: gpu: img: Future-proofing enhancements Matt Coster
@ 2025-03-20 11:32 ` Matt Coster
2025-03-21 8:10 ` Krzysztof Kozlowski
2025-03-20 11:32 ` [PATCH v4 03/18] drm/imagination: Update register defs for newer GPUs Matt Coster
` (15 subsequent siblings)
17 siblings, 1 reply; 21+ messages in thread
From: Matt Coster @ 2025-03-20 11:32 UTC (permalink / raw)
To: Frank Binns, Matt Coster, David Airlie, Simona Vetter,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Nishanth Menon,
Vignesh Raghavendra, Tero Kristo
Cc: dri-devel, devicetree, linux-kernel, linux-arm-kernel,
Randolph Sapp, Darren Etheridge, Michal Wilczynski, Alessio Belle,
Alexandru Dadu
Unlike AXE-1-16M, BXS-4-64 uses two power domains.
Like the existing AXE-1-16M integration, BXS-4-64 uses the single clock
integration in the TI k3-j721s2.
Signed-off-by: Matt Coster <matt.coster@imgtec.com>
---
Changes in v4:
- Add minItems: 1 to power-domain-names so we don't break single domain
bindings
- Add back power-domains to conditional constraints to match
power-domain-names
- Link to v3: https://lore.kernel.org/r/20250310-sets-bxs-4-64-patch-v1-v3-2-143b3dbef02f@imgtec.com
Changes in v3:
- Include adding the second power domain so it's in context
- Remove unnecessary example
- Link to v2: https://lore.kernel.org/r/20241118-sets-bxs-4-64-patch-v1-v2-8-3fd45d9fb0cf@imgtec.com
Changes in v2:
- Use normal reg syntax for 64-bit values
- Link to v1: https://lore.kernel.org/r/20241105-sets-bxs-4-64-patch-v1-v1-8-4ed30e865892@imgtec.com
---
.../devicetree/bindings/gpu/img,powervr-rogue.yaml | 37 ++++++++++++++++++++--
1 file changed, 35 insertions(+), 2 deletions(-)
diff --git a/Documentation/devicetree/bindings/gpu/img,powervr-rogue.yaml b/Documentation/devicetree/bindings/gpu/img,powervr-rogue.yaml
index 2a692feb5bcd526788117fce7934eef9521b364d..f82139f3b2c897bafd36e794cb7466941cc14e65 100644
--- a/Documentation/devicetree/bindings/gpu/img,powervr-rogue.yaml
+++ b/Documentation/devicetree/bindings/gpu/img,powervr-rogue.yaml
@@ -21,6 +21,11 @@ properties:
# work with newer dts.
- const: img,img-axe
- const: img,img-rogue
+ - items:
+ - enum:
+ - ti,j721s2-gpu
+ - const: img,img-bxs-4-64
+ - const: img,img-rogue
# This legacy combination of compatible strings was introduced early on
# before the more specific GPU identifiers were used.
@@ -49,11 +54,13 @@ properties:
power-domains:
minItems: 1
- maxItems: 1
+ maxItems: 2
power-domain-names:
items:
- const: a
+ - const: b
+ minItems: 1
dma-coherent: true
@@ -83,7 +90,33 @@ allOf:
properties:
compatible:
contains:
- const: ti,am62-gpu
+ const: img,img-axe-1-16m
+ then:
+ properties:
+ power-domains:
+ maxItems: 1
+ power-domain-names:
+ maxItems: 1
+
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: img,img-bxs-4-64
+ then:
+ properties:
+ power-domains:
+ minItems: 2
+ power-domain-names:
+ minItems: 2
+
+ - if:
+ properties:
+ compatible:
+ contains:
+ anyOf:
+ - const: ti,am62-gpu
+ - const: ti,j721s2-gpu
then:
properties:
clocks:
--
2.49.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v4 03/18] drm/imagination: Update register defs for newer GPUs
2025-03-20 11:32 [PATCH v4 00/18] Imagination BXS-4-64 MC1 GPU support Matt Coster
2025-03-20 11:32 ` [PATCH v4 01/18] dt-bindings: gpu: img: Future-proofing enhancements Matt Coster
2025-03-20 11:32 ` [PATCH v4 02/18] dt-bindings: gpu: img: Add BXS-4-64 devicetree bindings Matt Coster
@ 2025-03-20 11:32 ` Matt Coster
2025-03-20 11:32 ` [PATCH v4 04/18] drm/imagination: Use new generic compatible string Matt Coster
` (14 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Matt Coster @ 2025-03-20 11:32 UTC (permalink / raw)
To: Frank Binns, Matt Coster, David Airlie, Simona Vetter,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Nishanth Menon,
Vignesh Raghavendra, Tero Kristo
Cc: dri-devel, devicetree, linux-kernel, linux-arm-kernel,
Randolph Sapp, Darren Etheridge, Michal Wilczynski, Alessio Belle,
Alexandru Dadu
From: Alessio Belle <alessio.belle@imgtec.com>
Update the register define header to a newer version that covers more
recent GPUs, including BXS-4-64.
Signed-off-by: Alessio Belle <alessio.belle@imgtec.com>
Signed-off-by: Matt Coster <matt.coster@imgtec.com>
---
Changes in v4:
- None
- Link to v3: https://lore.kernel.org/r/20250310-sets-bxs-4-64-patch-v1-v3-3-143b3dbef02f@imgtec.com
Changes in v3:
- Added
---
drivers/gpu/drm/imagination/pvr_rogue_cr_defs.h | 153 +++++++++++++++++++++---
1 file changed, 134 insertions(+), 19 deletions(-)
diff --git a/drivers/gpu/drm/imagination/pvr_rogue_cr_defs.h b/drivers/gpu/drm/imagination/pvr_rogue_cr_defs.h
index 2a90d02796d3e071b18e18dead105e29798bcddc..790c97f80a2ac03ac76b933d009a2f9cfc6003f7 100644
--- a/drivers/gpu/drm/imagination/pvr_rogue_cr_defs.h
+++ b/drivers/gpu/drm/imagination/pvr_rogue_cr_defs.h
@@ -827,6 +827,120 @@
#define ROGUE_CR_EVENT_STATUS_TLA_COMPLETE_CLRMSK 0xFFFFFFFEU
#define ROGUE_CR_EVENT_STATUS_TLA_COMPLETE_EN 0x00000001U
+/* Register ROGUE_CR_EVENT_CLEAR */
+#define ROGUE_CR_EVENT_CLEAR 0x0138U
+#define ROGUE_CR_EVENT_CLEAR__ROGUEXE__MASKFULL 0x00000000E01DFFFFULL
+#define ROGUE_CR_EVENT_CLEAR__SIGNALS__MASKFULL 0x00000000E007FFFFULL
+#define ROGUE_CR_EVENT_CLEAR_MASKFULL 0x00000000FFFFFFFFULL
+#define ROGUE_CR_EVENT_CLEAR_TDM_FENCE_FINISHED_SHIFT 31U
+#define ROGUE_CR_EVENT_CLEAR_TDM_FENCE_FINISHED_CLRMSK 0x7FFFFFFFU
+#define ROGUE_CR_EVENT_CLEAR_TDM_FENCE_FINISHED_EN 0x80000000U
+#define ROGUE_CR_EVENT_CLEAR_TDM_BUFFER_STALL_SHIFT 30U
+#define ROGUE_CR_EVENT_CLEAR_TDM_BUFFER_STALL_CLRMSK 0xBFFFFFFFU
+#define ROGUE_CR_EVENT_CLEAR_TDM_BUFFER_STALL_EN 0x40000000U
+#define ROGUE_CR_EVENT_CLEAR_COMPUTE_SIGNAL_FAILURE_SHIFT 29U
+#define ROGUE_CR_EVENT_CLEAR_COMPUTE_SIGNAL_FAILURE_CLRMSK 0xDFFFFFFFU
+#define ROGUE_CR_EVENT_CLEAR_COMPUTE_SIGNAL_FAILURE_EN 0x20000000U
+#define ROGUE_CR_EVENT_CLEAR_DPX_OUT_OF_MEMORY_SHIFT 28U
+#define ROGUE_CR_EVENT_CLEAR_DPX_OUT_OF_MEMORY_CLRMSK 0xEFFFFFFFU
+#define ROGUE_CR_EVENT_CLEAR_DPX_OUT_OF_MEMORY_EN 0x10000000U
+#define ROGUE_CR_EVENT_CLEAR_DPX_MMU_PAGE_FAULT_SHIFT 27U
+#define ROGUE_CR_EVENT_CLEAR_DPX_MMU_PAGE_FAULT_CLRMSK 0xF7FFFFFFU
+#define ROGUE_CR_EVENT_CLEAR_DPX_MMU_PAGE_FAULT_EN 0x08000000U
+#define ROGUE_CR_EVENT_CLEAR_RPM_OUT_OF_MEMORY_SHIFT 26U
+#define ROGUE_CR_EVENT_CLEAR_RPM_OUT_OF_MEMORY_CLRMSK 0xFBFFFFFFU
+#define ROGUE_CR_EVENT_CLEAR_RPM_OUT_OF_MEMORY_EN 0x04000000U
+#define ROGUE_CR_EVENT_CLEAR_FBA_FC3_FINISHED_SHIFT 25U
+#define ROGUE_CR_EVENT_CLEAR_FBA_FC3_FINISHED_CLRMSK 0xFDFFFFFFU
+#define ROGUE_CR_EVENT_CLEAR_FBA_FC3_FINISHED_EN 0x02000000U
+#define ROGUE_CR_EVENT_CLEAR_FBA_FC2_FINISHED_SHIFT 24U
+#define ROGUE_CR_EVENT_CLEAR_FBA_FC2_FINISHED_CLRMSK 0xFEFFFFFFU
+#define ROGUE_CR_EVENT_CLEAR_FBA_FC2_FINISHED_EN 0x01000000U
+#define ROGUE_CR_EVENT_CLEAR_FBA_FC1_FINISHED_SHIFT 23U
+#define ROGUE_CR_EVENT_CLEAR_FBA_FC1_FINISHED_CLRMSK 0xFF7FFFFFU
+#define ROGUE_CR_EVENT_CLEAR_FBA_FC1_FINISHED_EN 0x00800000U
+#define ROGUE_CR_EVENT_CLEAR_FBA_FC0_FINISHED_SHIFT 22U
+#define ROGUE_CR_EVENT_CLEAR_FBA_FC0_FINISHED_CLRMSK 0xFFBFFFFFU
+#define ROGUE_CR_EVENT_CLEAR_FBA_FC0_FINISHED_EN 0x00400000U
+#define ROGUE_CR_EVENT_CLEAR_RDM_FC3_FINISHED_SHIFT 21U
+#define ROGUE_CR_EVENT_CLEAR_RDM_FC3_FINISHED_CLRMSK 0xFFDFFFFFU
+#define ROGUE_CR_EVENT_CLEAR_RDM_FC3_FINISHED_EN 0x00200000U
+#define ROGUE_CR_EVENT_CLEAR_RDM_FC2_FINISHED_SHIFT 20U
+#define ROGUE_CR_EVENT_CLEAR_RDM_FC2_FINISHED_CLRMSK 0xFFEFFFFFU
+#define ROGUE_CR_EVENT_CLEAR_RDM_FC2_FINISHED_EN 0x00100000U
+#define ROGUE_CR_EVENT_CLEAR_SAFETY_SHIFT 20U
+#define ROGUE_CR_EVENT_CLEAR_SAFETY_CLRMSK 0xFFEFFFFFU
+#define ROGUE_CR_EVENT_CLEAR_SAFETY_EN 0x00100000U
+#define ROGUE_CR_EVENT_CLEAR_RDM_FC1_FINISHED_SHIFT 19U
+#define ROGUE_CR_EVENT_CLEAR_RDM_FC1_FINISHED_CLRMSK 0xFFF7FFFFU
+#define ROGUE_CR_EVENT_CLEAR_RDM_FC1_FINISHED_EN 0x00080000U
+#define ROGUE_CR_EVENT_CLEAR_SLAVE_REQ_SHIFT 19U
+#define ROGUE_CR_EVENT_CLEAR_SLAVE_REQ_CLRMSK 0xFFF7FFFFU
+#define ROGUE_CR_EVENT_CLEAR_SLAVE_REQ_EN 0x00080000U
+#define ROGUE_CR_EVENT_CLEAR_RDM_FC0_FINISHED_SHIFT 18U
+#define ROGUE_CR_EVENT_CLEAR_RDM_FC0_FINISHED_CLRMSK 0xFFFBFFFFU
+#define ROGUE_CR_EVENT_CLEAR_RDM_FC0_FINISHED_EN 0x00040000U
+#define ROGUE_CR_EVENT_CLEAR_TDM_CONTEXT_STORE_FINISHED_SHIFT 18U
+#define ROGUE_CR_EVENT_CLEAR_TDM_CONTEXT_STORE_FINISHED_CLRMSK 0xFFFBFFFFU
+#define ROGUE_CR_EVENT_CLEAR_TDM_CONTEXT_STORE_FINISHED_EN 0x00040000U
+#define ROGUE_CR_EVENT_CLEAR_SHG_FINISHED_SHIFT 17U
+#define ROGUE_CR_EVENT_CLEAR_SHG_FINISHED_CLRMSK 0xFFFDFFFFU
+#define ROGUE_CR_EVENT_CLEAR_SHG_FINISHED_EN 0x00020000U
+#define ROGUE_CR_EVENT_CLEAR_SPFILTER_SIGNAL_UPDATE_SHIFT 17U
+#define ROGUE_CR_EVENT_CLEAR_SPFILTER_SIGNAL_UPDATE_CLRMSK 0xFFFDFFFFU
+#define ROGUE_CR_EVENT_CLEAR_SPFILTER_SIGNAL_UPDATE_EN 0x00020000U
+#define ROGUE_CR_EVENT_CLEAR_COMPUTE_BUFFER_STALL_SHIFT 16U
+#define ROGUE_CR_EVENT_CLEAR_COMPUTE_BUFFER_STALL_CLRMSK 0xFFFEFFFFU
+#define ROGUE_CR_EVENT_CLEAR_COMPUTE_BUFFER_STALL_EN 0x00010000U
+#define ROGUE_CR_EVENT_CLEAR_USC_TRIGGER_SHIFT 15U
+#define ROGUE_CR_EVENT_CLEAR_USC_TRIGGER_CLRMSK 0xFFFF7FFFU
+#define ROGUE_CR_EVENT_CLEAR_USC_TRIGGER_EN 0x00008000U
+#define ROGUE_CR_EVENT_CLEAR_ZLS_FINISHED_SHIFT 14U
+#define ROGUE_CR_EVENT_CLEAR_ZLS_FINISHED_CLRMSK 0xFFFFBFFFU
+#define ROGUE_CR_EVENT_CLEAR_ZLS_FINISHED_EN 0x00004000U
+#define ROGUE_CR_EVENT_CLEAR_GPIO_ACK_SHIFT 13U
+#define ROGUE_CR_EVENT_CLEAR_GPIO_ACK_CLRMSK 0xFFFFDFFFU
+#define ROGUE_CR_EVENT_CLEAR_GPIO_ACK_EN 0x00002000U
+#define ROGUE_CR_EVENT_CLEAR_GPIO_REQ_SHIFT 12U
+#define ROGUE_CR_EVENT_CLEAR_GPIO_REQ_CLRMSK 0xFFFFEFFFU
+#define ROGUE_CR_EVENT_CLEAR_GPIO_REQ_EN 0x00001000U
+#define ROGUE_CR_EVENT_CLEAR_POWER_ABORT_SHIFT 11U
+#define ROGUE_CR_EVENT_CLEAR_POWER_ABORT_CLRMSK 0xFFFFF7FFU
+#define ROGUE_CR_EVENT_CLEAR_POWER_ABORT_EN 0x00000800U
+#define ROGUE_CR_EVENT_CLEAR_POWER_COMPLETE_SHIFT 10U
+#define ROGUE_CR_EVENT_CLEAR_POWER_COMPLETE_CLRMSK 0xFFFFFBFFU
+#define ROGUE_CR_EVENT_CLEAR_POWER_COMPLETE_EN 0x00000400U
+#define ROGUE_CR_EVENT_CLEAR_MMU_PAGE_FAULT_SHIFT 9U
+#define ROGUE_CR_EVENT_CLEAR_MMU_PAGE_FAULT_CLRMSK 0xFFFFFDFFU
+#define ROGUE_CR_EVENT_CLEAR_MMU_PAGE_FAULT_EN 0x00000200U
+#define ROGUE_CR_EVENT_CLEAR_PM_3D_MEM_FREE_SHIFT 8U
+#define ROGUE_CR_EVENT_CLEAR_PM_3D_MEM_FREE_CLRMSK 0xFFFFFEFFU
+#define ROGUE_CR_EVENT_CLEAR_PM_3D_MEM_FREE_EN 0x00000100U
+#define ROGUE_CR_EVENT_CLEAR_PM_OUT_OF_MEMORY_SHIFT 7U
+#define ROGUE_CR_EVENT_CLEAR_PM_OUT_OF_MEMORY_CLRMSK 0xFFFFFF7FU
+#define ROGUE_CR_EVENT_CLEAR_PM_OUT_OF_MEMORY_EN 0x00000080U
+#define ROGUE_CR_EVENT_CLEAR_TA_TERMINATE_SHIFT 6U
+#define ROGUE_CR_EVENT_CLEAR_TA_TERMINATE_CLRMSK 0xFFFFFFBFU
+#define ROGUE_CR_EVENT_CLEAR_TA_TERMINATE_EN 0x00000040U
+#define ROGUE_CR_EVENT_CLEAR_TA_FINISHED_SHIFT 5U
+#define ROGUE_CR_EVENT_CLEAR_TA_FINISHED_CLRMSK 0xFFFFFFDFU
+#define ROGUE_CR_EVENT_CLEAR_TA_FINISHED_EN 0x00000020U
+#define ROGUE_CR_EVENT_CLEAR_ISP_END_MACROTILE_SHIFT 4U
+#define ROGUE_CR_EVENT_CLEAR_ISP_END_MACROTILE_CLRMSK 0xFFFFFFEFU
+#define ROGUE_CR_EVENT_CLEAR_ISP_END_MACROTILE_EN 0x00000010U
+#define ROGUE_CR_EVENT_CLEAR_PIXELBE_END_RENDER_SHIFT 3U
+#define ROGUE_CR_EVENT_CLEAR_PIXELBE_END_RENDER_CLRMSK 0xFFFFFFF7U
+#define ROGUE_CR_EVENT_CLEAR_PIXELBE_END_RENDER_EN 0x00000008U
+#define ROGUE_CR_EVENT_CLEAR_COMPUTE_FINISHED_SHIFT 2U
+#define ROGUE_CR_EVENT_CLEAR_COMPUTE_FINISHED_CLRMSK 0xFFFFFFFBU
+#define ROGUE_CR_EVENT_CLEAR_COMPUTE_FINISHED_EN 0x00000004U
+#define ROGUE_CR_EVENT_CLEAR_KERNEL_FINISHED_SHIFT 1U
+#define ROGUE_CR_EVENT_CLEAR_KERNEL_FINISHED_CLRMSK 0xFFFFFFFDU
+#define ROGUE_CR_EVENT_CLEAR_KERNEL_FINISHED_EN 0x00000002U
+#define ROGUE_CR_EVENT_CLEAR_TLA_COMPLETE_SHIFT 0U
+#define ROGUE_CR_EVENT_CLEAR_TLA_COMPLETE_CLRMSK 0xFFFFFFFEU
+#define ROGUE_CR_EVENT_CLEAR_TLA_COMPLETE_EN 0x00000001U
+
/* Register ROGUE_CR_TIMER */
#define ROGUE_CR_TIMER 0x0160U
#define ROGUE_CR_TIMER_MASKFULL 0x8000FFFFFFFFFFFFULL
@@ -6031,25 +6145,6 @@
#define ROGUE_CR_MULTICORE_COMPUTE_CTRL_COMMON_GPU_ENABLE_SHIFT 0U
#define ROGUE_CR_MULTICORE_COMPUTE_CTRL_COMMON_GPU_ENABLE_CLRMSK 0xFFFFFF00U
-/* Register ROGUE_CR_ECC_RAM_ERR_INJ */
-#define ROGUE_CR_ECC_RAM_ERR_INJ 0xF340U
-#define ROGUE_CR_ECC_RAM_ERR_INJ_MASKFULL 0x000000000000001FULL
-#define ROGUE_CR_ECC_RAM_ERR_INJ_SLC_SIDEKICK_SHIFT 4U
-#define ROGUE_CR_ECC_RAM_ERR_INJ_SLC_SIDEKICK_CLRMSK 0xFFFFFFEFU
-#define ROGUE_CR_ECC_RAM_ERR_INJ_SLC_SIDEKICK_EN 0x00000010U
-#define ROGUE_CR_ECC_RAM_ERR_INJ_USC_SHIFT 3U
-#define ROGUE_CR_ECC_RAM_ERR_INJ_USC_CLRMSK 0xFFFFFFF7U
-#define ROGUE_CR_ECC_RAM_ERR_INJ_USC_EN 0x00000008U
-#define ROGUE_CR_ECC_RAM_ERR_INJ_TPU_MCU_L0_SHIFT 2U
-#define ROGUE_CR_ECC_RAM_ERR_INJ_TPU_MCU_L0_CLRMSK 0xFFFFFFFBU
-#define ROGUE_CR_ECC_RAM_ERR_INJ_TPU_MCU_L0_EN 0x00000004U
-#define ROGUE_CR_ECC_RAM_ERR_INJ_RASCAL_SHIFT 1U
-#define ROGUE_CR_ECC_RAM_ERR_INJ_RASCAL_CLRMSK 0xFFFFFFFDU
-#define ROGUE_CR_ECC_RAM_ERR_INJ_RASCAL_EN 0x00000002U
-#define ROGUE_CR_ECC_RAM_ERR_INJ_MARS_SHIFT 0U
-#define ROGUE_CR_ECC_RAM_ERR_INJ_MARS_CLRMSK 0xFFFFFFFEU
-#define ROGUE_CR_ECC_RAM_ERR_INJ_MARS_EN 0x00000001U
-
/* Register ROGUE_CR_ECC_RAM_INIT_KICK */
#define ROGUE_CR_ECC_RAM_INIT_KICK 0xF348U
#define ROGUE_CR_ECC_RAM_INIT_KICK_MASKFULL 0x000000000000001FULL
@@ -6163,6 +6258,26 @@
#define ROGUE_CR_SAFETY_EVENT_CLEAR__ROGUEXE__GPU_PAGE_FAULT_CLRMSK 0xFFFFFFFEU
#define ROGUE_CR_SAFETY_EVENT_CLEAR__ROGUEXE__GPU_PAGE_FAULT_EN 0x00000001U
+/* Register ROGUE_CR_FAULT_FW_STATUS */
+#define ROGUE_CR_FAULT_FW_STATUS 0xF3B0U
+#define ROGUE_CR_FAULT_FW_STATUS_MASKFULL 0x0000000000010001ULL
+#define ROGUE_CR_FAULT_FW_STATUS_CPU_CORRECT_SHIFT 16U
+#define ROGUE_CR_FAULT_FW_STATUS_CPU_CORRECT_CLRMSK 0xFFFEFFFFU
+#define ROGUE_CR_FAULT_FW_STATUS_CPU_CORRECT_EN 0x00010000U
+#define ROGUE_CR_FAULT_FW_STATUS_CPU_DETECT_SHIFT 0U
+#define ROGUE_CR_FAULT_FW_STATUS_CPU_DETECT_CLRMSK 0xFFFFFFFEU
+#define ROGUE_CR_FAULT_FW_STATUS_CPU_DETECT_EN 0x00000001U
+
+/* Register ROGUE_CR_FAULT_FW_CLEAR */
+#define ROGUE_CR_FAULT_FW_CLEAR 0xF3B8U
+#define ROGUE_CR_FAULT_FW_CLEAR_MASKFULL 0x0000000000010001ULL
+#define ROGUE_CR_FAULT_FW_CLEAR_CPU_CORRECT_SHIFT 16U
+#define ROGUE_CR_FAULT_FW_CLEAR_CPU_CORRECT_CLRMSK 0xFFFEFFFFU
+#define ROGUE_CR_FAULT_FW_CLEAR_CPU_CORRECT_EN 0x00010000U
+#define ROGUE_CR_FAULT_FW_CLEAR_CPU_DETECT_SHIFT 0U
+#define ROGUE_CR_FAULT_FW_CLEAR_CPU_DETECT_CLRMSK 0xFFFFFFFEU
+#define ROGUE_CR_FAULT_FW_CLEAR_CPU_DETECT_EN 0x00000001U
+
/* Register ROGUE_CR_MTS_SAFETY_EVENT_ENABLE */
#define ROGUE_CR_MTS_SAFETY_EVENT_ENABLE__ROGUEXE 0xF3D8U
#define ROGUE_CR_MTS_SAFETY_EVENT_ENABLE__ROGUEXE__MASKFULL 0x000000000000007FULL
--
2.49.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v4 04/18] drm/imagination: Use new generic compatible string
2025-03-20 11:32 [PATCH v4 00/18] Imagination BXS-4-64 MC1 GPU support Matt Coster
` (2 preceding siblings ...)
2025-03-20 11:32 ` [PATCH v4 03/18] drm/imagination: Update register defs for newer GPUs Matt Coster
@ 2025-03-20 11:32 ` Matt Coster
2025-03-20 11:32 ` [PATCH v4 05/18] drm/imagination: Add power domain control Matt Coster
` (13 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Matt Coster @ 2025-03-20 11:32 UTC (permalink / raw)
To: Frank Binns, Matt Coster, David Airlie, Simona Vetter,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Nishanth Menon,
Vignesh Raghavendra, Tero Kristo
Cc: dri-devel, devicetree, linux-kernel, linux-arm-kernel,
Randolph Sapp, Darren Etheridge, Michal Wilczynski, Alessio Belle,
Alexandru Dadu
Follow-on from the companion dt-bindings change ("dt-bindings: gpu: img:
More explicit compatible strings"), deprecating "img,img-axe" in favour of
the more explicit combination of "img,img-rogue" and "img,img-axe-1-16m".
Since all relevant details are interrogated from the device at runtime,
we can match on the generic "img,img-rogue" and avoid adding more entries
with NULL data members (barring hardware quirks).
Signed-off-by: Matt Coster <matt.coster@imgtec.com>
---
Changes in v4:
- None
- Link to v3: https://lore.kernel.org/r/20250310-sets-bxs-4-64-patch-v1-v3-4-143b3dbef02f@imgtec.com
Changes in v3:
- Don't use more specific compatible strings when not required
- Link to v2: https://lore.kernel.org/r/20241118-sets-bxs-4-64-patch-v1-v2-5-3fd45d9fb0cf@imgtec.com
Changes in v2:
- None
- Link to v1: https://lore.kernel.org/r/20241105-sets-bxs-4-64-patch-v1-v1-5-4ed30e865892@imgtec.com
---
drivers/gpu/drm/imagination/pvr_drv.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/gpu/drm/imagination/pvr_drv.c b/drivers/gpu/drm/imagination/pvr_drv.c
index 0639502137b4431dc23a349476572cc898d1f8d0..3130193f8fffc185e630a293be53374bdc4b7ce0 100644
--- a/drivers/gpu/drm/imagination/pvr_drv.c
+++ b/drivers/gpu/drm/imagination/pvr_drv.c
@@ -1473,6 +1473,13 @@ static void pvr_remove(struct platform_device *plat_dev)
}
static const struct of_device_id dt_match[] = {
+ { .compatible = "img,img-rogue", .data = NULL },
+
+ /*
+ * This legacy compatible string was introduced early on before the more generic
+ * "img,img-rogue" was added. Keep it around here for compatibility, but never use
+ * "img,img-axe" in new devicetrees.
+ */
{ .compatible = "img,img-axe", .data = NULL },
{}
};
--
2.49.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v4 05/18] drm/imagination: Add power domain control
2025-03-20 11:32 [PATCH v4 00/18] Imagination BXS-4-64 MC1 GPU support Matt Coster
` (3 preceding siblings ...)
2025-03-20 11:32 ` [PATCH v4 04/18] drm/imagination: Use new generic compatible string Matt Coster
@ 2025-03-20 11:32 ` Matt Coster
2025-03-20 11:32 ` [PATCH v4 06/18] drm/imagination: Mask GPU IRQs in threaded handler Matt Coster
` (12 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Matt Coster @ 2025-03-20 11:32 UTC (permalink / raw)
To: Frank Binns, Matt Coster, David Airlie, Simona Vetter,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Nishanth Menon,
Vignesh Raghavendra, Tero Kristo
Cc: dri-devel, devicetree, linux-kernel, linux-arm-kernel,
Randolph Sapp, Darren Etheridge, Michal Wilczynski, Alessio Belle,
Alexandru Dadu
The first supported GPU only used a single power domain so this was
automatically handled by the device runtime.
In order to support multiple power domains, they must be enumerated from
devicetree and linked to both the GPU device and each other to ensure
correct power sequencing at start time.
For all Imagination Rogue GPUs, power domains are named "a", "b", etc. and
the sequence A->B->... is always valid for startup with the reverse true
for shutdown. Note this is not always the *only* valid sequence, but it's
simple and does not require special-casing for different GPU power
topologies.
Signed-off-by: Matt Coster <matt.coster@imgtec.com>
---
Changes in v4:
- None
- Link to v3: https://lore.kernel.org/r/20250310-sets-bxs-4-64-patch-v1-v3-5-143b3dbef02f@imgtec.com
Changes in v3:
- None
- Link to v2: https://lore.kernel.org/r/20241118-sets-bxs-4-64-patch-v1-v2-6-3fd45d9fb0cf@imgtec.com
Changes in v2:
- None
- Link to v1: https://lore.kernel.org/r/20241105-sets-bxs-4-64-patch-v1-v1-6-4ed30e865892@imgtec.com
---
drivers/gpu/drm/imagination/pvr_device.h | 8 +++
drivers/gpu/drm/imagination/pvr_drv.c | 7 ++
drivers/gpu/drm/imagination/pvr_power.c | 114 +++++++++++++++++++++++++++++++
drivers/gpu/drm/imagination/pvr_power.h | 3 +
4 files changed, 132 insertions(+)
diff --git a/drivers/gpu/drm/imagination/pvr_device.h b/drivers/gpu/drm/imagination/pvr_device.h
index 6d0dfacb677b46a880f37f419dfa7b67c68fe63d..2dd8a8885fe07078896d669d822525fb2b7bab51 100644
--- a/drivers/gpu/drm/imagination/pvr_device.h
+++ b/drivers/gpu/drm/imagination/pvr_device.h
@@ -18,6 +18,7 @@
#include <linux/bits.h>
#include <linux/compiler_attributes.h>
#include <linux/compiler_types.h>
+#include <linux/device.h>
#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/kernel.h>
@@ -131,6 +132,13 @@ struct pvr_device {
*/
struct clk *mem_clk;
+ struct pvr_device_power {
+ struct device **domain_devs;
+ struct device_link **domain_links;
+
+ u32 domain_count;
+ } power;
+
/** @irq: IRQ number. */
int irq;
diff --git a/drivers/gpu/drm/imagination/pvr_drv.c b/drivers/gpu/drm/imagination/pvr_drv.c
index 3130193f8fffc185e630a293be53374bdc4b7ce0..ac4f5855c5692f0956862cebdbf76b16d8da9a81 100644
--- a/drivers/gpu/drm/imagination/pvr_drv.c
+++ b/drivers/gpu/drm/imagination/pvr_drv.c
@@ -1411,6 +1411,10 @@ pvr_probe(struct platform_device *plat_dev)
platform_set_drvdata(plat_dev, drm_dev);
+ err = pvr_power_domains_init(pvr_dev);
+ if (err)
+ return err;
+
init_rwsem(&pvr_dev->reset_sem);
pvr_context_device_init(pvr_dev);
@@ -1450,6 +1454,8 @@ pvr_probe(struct platform_device *plat_dev)
err_context_fini:
pvr_context_device_fini(pvr_dev);
+ pvr_power_domains_fini(pvr_dev);
+
return err;
}
@@ -1470,6 +1476,7 @@ static void pvr_remove(struct platform_device *plat_dev)
pvr_watchdog_fini(pvr_dev);
pvr_queue_device_fini(pvr_dev);
pvr_context_device_fini(pvr_dev);
+ pvr_power_domains_fini(pvr_dev);
}
static const struct of_device_id dt_match[] = {
diff --git a/drivers/gpu/drm/imagination/pvr_power.c b/drivers/gpu/drm/imagination/pvr_power.c
index ba7816fd28ec77e6ca5ce408302a413ce1afeb6e..19b079b357df78e8bcdecfa377fc9c05b6e8e4b0 100644
--- a/drivers/gpu/drm/imagination/pvr_power.c
+++ b/drivers/gpu/drm/imagination/pvr_power.c
@@ -10,10 +10,13 @@
#include <drm/drm_drv.h>
#include <drm/drm_managed.h>
+#include <linux/cleanup.h>
#include <linux/clk.h>
#include <linux/interrupt.h>
#include <linux/mutex.h>
+#include <linux/of.h>
#include <linux/platform_device.h>
+#include <linux/pm_domain.h>
#include <linux/pm_runtime.h>
#include <linux/timer.h>
#include <linux/types.h>
@@ -431,3 +434,114 @@ pvr_watchdog_fini(struct pvr_device *pvr_dev)
{
cancel_delayed_work_sync(&pvr_dev->watchdog.work);
}
+
+int pvr_power_domains_init(struct pvr_device *pvr_dev)
+{
+ struct device *dev = from_pvr_device(pvr_dev)->dev;
+
+ struct device_link **domain_links __free(kfree) = NULL;
+ struct device **domain_devs __free(kfree) = NULL;
+ int domain_count;
+ int link_count;
+
+ char dev_name[2] = "a";
+ int err;
+ int i;
+
+ domain_count = of_count_phandle_with_args(dev->of_node, "power-domains",
+ "#power-domain-cells");
+ if (domain_count < 0)
+ return domain_count;
+
+ if (domain_count <= 1)
+ return 0;
+
+ link_count = domain_count + (domain_count - 1);
+
+ domain_devs = kcalloc(domain_count, sizeof(*domain_devs), GFP_KERNEL);
+ if (!domain_devs)
+ return -ENOMEM;
+
+ domain_links = kcalloc(link_count, sizeof(*domain_links), GFP_KERNEL);
+ if (!domain_links)
+ return -ENOMEM;
+
+ for (i = 0; i < domain_count; i++) {
+ struct device *domain_dev;
+
+ dev_name[0] = 'a' + i;
+ domain_dev = dev_pm_domain_attach_by_name(dev, dev_name);
+ if (IS_ERR_OR_NULL(domain_dev)) {
+ err = domain_dev ? PTR_ERR(domain_dev) : -ENODEV;
+ goto err_detach;
+ }
+
+ domain_devs[i] = domain_dev;
+ }
+
+ for (i = 0; i < domain_count; i++) {
+ struct device_link *link;
+
+ link = device_link_add(dev, domain_devs[i], DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME);
+ if (!link) {
+ err = -ENODEV;
+ goto err_unlink;
+ }
+
+ domain_links[i] = link;
+ }
+
+ for (i = domain_count; i < link_count; i++) {
+ struct device_link *link;
+
+ link = device_link_add(domain_devs[i - domain_count + 1],
+ domain_devs[i - domain_count],
+ DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME);
+ if (!link) {
+ err = -ENODEV;
+ goto err_unlink;
+ }
+
+ domain_links[i] = link;
+ }
+
+ pvr_dev->power = (struct pvr_device_power){
+ .domain_devs = no_free_ptr(domain_devs),
+ .domain_links = no_free_ptr(domain_links),
+ .domain_count = domain_count,
+ };
+
+ return 0;
+
+err_unlink:
+ while (--i >= 0)
+ device_link_del(domain_links[i]);
+
+ i = domain_count;
+
+err_detach:
+ while (--i >= 0)
+ dev_pm_domain_detach(domain_devs[i], true);
+
+ return err;
+}
+
+void pvr_power_domains_fini(struct pvr_device *pvr_dev)
+{
+ const int domain_count = pvr_dev->power.domain_count;
+
+ int i = domain_count + (domain_count - 1);
+
+ while (--i >= 0)
+ device_link_del(pvr_dev->power.domain_links[i]);
+
+ i = domain_count;
+
+ while (--i >= 0)
+ dev_pm_domain_detach(pvr_dev->power.domain_devs[i], true);
+
+ kfree(pvr_dev->power.domain_links);
+ kfree(pvr_dev->power.domain_devs);
+
+ pvr_dev->power = (struct pvr_device_power){ 0 };
+}
diff --git a/drivers/gpu/drm/imagination/pvr_power.h b/drivers/gpu/drm/imagination/pvr_power.h
index 9a9312dcb2dab7d36ee8ff7f69e69d126c5469a9..ada85674a7ca762dcf92df40424230e1c3910342 100644
--- a/drivers/gpu/drm/imagination/pvr_power.h
+++ b/drivers/gpu/drm/imagination/pvr_power.h
@@ -38,4 +38,7 @@ pvr_power_put(struct pvr_device *pvr_dev)
return pm_runtime_put(drm_dev->dev);
}
+int pvr_power_domains_init(struct pvr_device *pvr_dev);
+void pvr_power_domains_fini(struct pvr_device *pvr_dev);
+
#endif /* PVR_POWER_H */
--
2.49.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v4 06/18] drm/imagination: Mask GPU IRQs in threaded handler
2025-03-20 11:32 [PATCH v4 00/18] Imagination BXS-4-64 MC1 GPU support Matt Coster
` (4 preceding siblings ...)
2025-03-20 11:32 ` [PATCH v4 05/18] drm/imagination: Add power domain control Matt Coster
@ 2025-03-20 11:32 ` Matt Coster
2025-03-20 11:32 ` [PATCH v4 07/18] drm/imagination: Handle Rogue safety event IRQs Matt Coster
` (11 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Matt Coster @ 2025-03-20 11:32 UTC (permalink / raw)
To: Frank Binns, Matt Coster, David Airlie, Simona Vetter,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Nishanth Menon,
Vignesh Raghavendra, Tero Kristo
Cc: dri-devel, devicetree, linux-kernel, linux-arm-kernel,
Randolph Sapp, Darren Etheridge, Michal Wilczynski, Alessio Belle,
Alexandru Dadu
From: Alessio Belle <alessio.belle@imgtec.com>
Pass IRQF_ONESHOT flag to request_threaded_irq(), so that interrupts will
be masked by the kernel until the end of the threaded IRQ handler. Since
the calls to pvr_fw_irq_enable() and pvr_fw_irq_disable() are now
redundant, remove them.
Interrupts to the host from the soon-to-be-added RISC-V firmware
processors cannot be masked in hardware. This change allows us to continue
using the threaded handler in GPUs with a RISC-V firmware.
For simplicity, the same approach is taken for all firmware processors.
Signed-off-by: Alessio Belle <alessio.belle@imgtec.com>
Signed-off-by: Matt Coster <matt.coster@imgtec.com>
---
Changes in v4:
- None
- Link to v3: https://lore.kernel.org/r/20250310-sets-bxs-4-64-patch-v1-v3-6-143b3dbef02f@imgtec.com
Changes in v3:
- Added
---
drivers/gpu/drm/imagination/pvr_device.c | 12 +++++-------
1 file changed, 5 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/imagination/pvr_device.c b/drivers/gpu/drm/imagination/pvr_device.c
index 1704c0268589bdeb65fa6535f9ec63182b0a3e94..b6ce936f07c8bb26d240e50b72a1d991dbe4b045 100644
--- a/drivers/gpu/drm/imagination/pvr_device.c
+++ b/drivers/gpu/drm/imagination/pvr_device.c
@@ -169,8 +169,6 @@ static irqreturn_t pvr_device_irq_thread_handler(int irq, void *data)
ret = IRQ_HANDLED;
}
- /* Unmask FW irqs before returning, so new interrupts can be received. */
- pvr_fw_irq_enable(pvr_dev);
return ret;
}
@@ -181,10 +179,6 @@ static irqreturn_t pvr_device_irq_handler(int irq, void *data)
if (!pvr_fw_irq_pending(pvr_dev))
return IRQ_NONE; /* Spurious IRQ - ignore. */
- /* Mask the FW interrupts before waking up the thread. Will be unmasked
- * when the thread handler is done processing events.
- */
- pvr_fw_irq_disable(pvr_dev);
return IRQ_WAKE_THREAD;
}
@@ -213,9 +207,13 @@ pvr_device_irq_init(struct pvr_device *pvr_dev)
pvr_fw_irq_clear(pvr_dev);
pvr_fw_irq_enable(pvr_dev);
+ /*
+ * The ONESHOT flag ensures IRQs are masked while the thread handler is
+ * running.
+ */
return request_threaded_irq(pvr_dev->irq, pvr_device_irq_handler,
pvr_device_irq_thread_handler,
- IRQF_SHARED, "gpu", pvr_dev);
+ IRQF_SHARED | IRQF_ONESHOT, "gpu", pvr_dev);
}
/**
--
2.49.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v4 07/18] drm/imagination: Handle Rogue safety event IRQs
2025-03-20 11:32 [PATCH v4 00/18] Imagination BXS-4-64 MC1 GPU support Matt Coster
` (5 preceding siblings ...)
2025-03-20 11:32 ` [PATCH v4 06/18] drm/imagination: Mask GPU IRQs in threaded handler Matt Coster
@ 2025-03-20 11:32 ` Matt Coster
2025-03-20 11:32 ` [PATCH v4 08/18] drm/imagination: Remove firmware enable_reg Matt Coster
` (10 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Matt Coster @ 2025-03-20 11:32 UTC (permalink / raw)
To: Frank Binns, Matt Coster, David Airlie, Simona Vetter,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Nishanth Menon,
Vignesh Raghavendra, Tero Kristo
Cc: dri-devel, devicetree, linux-kernel, linux-arm-kernel,
Randolph Sapp, Darren Etheridge, Michal Wilczynski, Alessio Belle,
Alexandru Dadu
From: Alessio Belle <alessio.belle@imgtec.com>
Extend interrupt handling logic to check for safety event IRQs, then clear
and handle them in the IRQ handler thread.
Safety events need to be checked and cleared with a different set of GPU
registers than those the IRQ handler has been using so far.
Only two safety events need to be handled on the host: FW fault (ECC error
correction or detection) and device watchdog timeout. Handling right now
simply consists of clearing any error and logging the event. If either of
these events results in an unrecoverable GPU or FW, the driver will
eventually attempt to recover from it e.g. via pvr_power_reset().
Note that Rogue GPUs may send interrupts to the host for all types of
safety events, not just the two above. For events not handled by the host,
clearing the associated interrupt is sufficient.
Signed-off-by: Alessio Belle <alessio.belle@imgtec.com>
Signed-off-by: Matt Coster <matt.coster@imgtec.com>
---
Changes in v4:
- Only invoke pvr_device_safety_irq_clear() if has_safety_events is set
- Link to v3: https://lore.kernel.org/r/20250310-sets-bxs-4-64-patch-v1-v3-7-143b3dbef02f@imgtec.com
Changes in v3:
- Added
---
drivers/gpu/drm/imagination/pvr_device.c | 113 ++++++++++++++++++++++++++++++-
drivers/gpu/drm/imagination/pvr_device.h | 3 +
drivers/gpu/drm/imagination/pvr_fw.c | 3 +
3 files changed, 117 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/imagination/pvr_device.c b/drivers/gpu/drm/imagination/pvr_device.c
index b6ce936f07c8bb26d240e50b72a1d991dbe4b045..a47dd1dd82432f1d66ff90aca26b7b264f4068df 100644
--- a/drivers/gpu/drm/imagination/pvr_device.c
+++ b/drivers/gpu/drm/imagination/pvr_device.c
@@ -146,9 +146,61 @@ static void pvr_device_process_active_queues(struct pvr_device *pvr_dev)
mutex_unlock(&pvr_dev->queues.lock);
}
+static bool pvr_device_safety_irq_pending(struct pvr_device *pvr_dev)
+{
+ u32 events;
+
+ WARN_ON_ONCE(!pvr_dev->has_safety_events);
+
+ events = pvr_cr_read32(pvr_dev, ROGUE_CR_EVENT_STATUS);
+
+ return (events & ROGUE_CR_EVENT_STATUS_SAFETY_EN) != 0;
+}
+
+static void pvr_device_safety_irq_clear(struct pvr_device *pvr_dev)
+{
+ WARN_ON_ONCE(!pvr_dev->has_safety_events);
+
+ pvr_cr_write32(pvr_dev, ROGUE_CR_EVENT_CLEAR,
+ ROGUE_CR_EVENT_CLEAR_SAFETY_EN);
+}
+
+static void pvr_device_handle_safety_events(struct pvr_device *pvr_dev)
+{
+ struct drm_device *drm_dev = from_pvr_device(pvr_dev);
+ u32 events;
+
+ WARN_ON_ONCE(!pvr_dev->has_safety_events);
+
+ events = pvr_cr_read32(pvr_dev, ROGUE_CR_SAFETY_EVENT_STATUS__ROGUEXE);
+
+ /* Handle only these events on the host and leave the rest to the FW. */
+ events &= ROGUE_CR_SAFETY_EVENT_STATUS__ROGUEXE__FAULT_FW_EN |
+ ROGUE_CR_SAFETY_EVENT_STATUS__ROGUEXE__WATCHDOG_TIMEOUT_EN;
+
+ pvr_cr_write32(pvr_dev, ROGUE_CR_SAFETY_EVENT_CLEAR__ROGUEXE, events);
+
+ if (events & ROGUE_CR_SAFETY_EVENT_STATUS__ROGUEXE__FAULT_FW_EN) {
+ u32 fault_fw = pvr_cr_read32(pvr_dev, ROGUE_CR_FAULT_FW_STATUS);
+
+ pvr_cr_write32(pvr_dev, ROGUE_CR_FAULT_FW_CLEAR, fault_fw);
+
+ drm_info(drm_dev, "Safety event: FW fault (mask=0x%08x)\n", fault_fw);
+ }
+
+ if (events & ROGUE_CR_SAFETY_EVENT_STATUS__ROGUEXE__WATCHDOG_TIMEOUT_EN) {
+ /*
+ * The watchdog timer is disabled by the driver so this event
+ * should never be fired.
+ */
+ drm_info(drm_dev, "Safety event: Watchdog timeout\n");
+ }
+}
+
static irqreturn_t pvr_device_irq_thread_handler(int irq, void *data)
{
struct pvr_device *pvr_dev = data;
+ struct drm_device *drm_dev = from_pvr_device(pvr_dev);
irqreturn_t ret = IRQ_NONE;
/* We are in the threaded handler, we can keep dequeuing events until we
@@ -164,24 +216,76 @@ static irqreturn_t pvr_device_irq_thread_handler(int irq, void *data)
pvr_device_process_active_queues(pvr_dev);
}
- pm_runtime_mark_last_busy(from_pvr_device(pvr_dev)->dev);
+ pm_runtime_mark_last_busy(drm_dev->dev);
ret = IRQ_HANDLED;
}
+ if (pvr_dev->has_safety_events) {
+ int err;
+
+ /*
+ * Ensure the GPU is powered on since some safety events (such
+ * as ECC faults) can happen outside of job submissions, which
+ * are otherwise the only time a power reference is held.
+ */
+ err = pvr_power_get(pvr_dev);
+ if (err) {
+ drm_err_ratelimited(drm_dev,
+ "%s: could not take power reference (%d)\n",
+ __func__, err);
+ return ret;
+ }
+
+ while (pvr_device_safety_irq_pending(pvr_dev)) {
+ pvr_device_safety_irq_clear(pvr_dev);
+ pvr_device_handle_safety_events(pvr_dev);
+
+ ret = IRQ_HANDLED;
+ }
+
+ pvr_power_put(pvr_dev);
+ }
+
return ret;
}
static irqreturn_t pvr_device_irq_handler(int irq, void *data)
{
struct pvr_device *pvr_dev = data;
+ bool safety_irq_pending = false;
+
+ if (pvr_dev->has_safety_events)
+ safety_irq_pending = pvr_device_safety_irq_pending(pvr_dev);
- if (!pvr_fw_irq_pending(pvr_dev))
+ if (!pvr_fw_irq_pending(pvr_dev) && !safety_irq_pending)
return IRQ_NONE; /* Spurious IRQ - ignore. */
return IRQ_WAKE_THREAD;
}
+static void pvr_device_safety_irq_init(struct pvr_device *pvr_dev)
+{
+ u32 num_ecc_rams = 0;
+
+ /*
+ * Safety events are an optional feature of the RogueXE platform. They
+ * are only enabled if at least one of ECC memory or the watchdog timer
+ * are present in HW. While safety events can be generated by other
+ * systems, that will never happen if the above mentioned hardware is
+ * not present.
+ */
+ if (!PVR_HAS_FEATURE(pvr_dev, roguexe)) {
+ pvr_dev->has_safety_events = false;
+ return;
+ }
+
+ PVR_FEATURE_VALUE(pvr_dev, ecc_rams, &num_ecc_rams);
+
+ pvr_dev->has_safety_events =
+ num_ecc_rams > 0 || PVR_HAS_FEATURE(pvr_dev, watchdog_timer);
+}
+
/**
* pvr_device_irq_init() - Initialise IRQ required by a PowerVR device
* @pvr_dev: Target PowerVR device.
@@ -199,6 +303,8 @@ pvr_device_irq_init(struct pvr_device *pvr_dev)
init_waitqueue_head(&pvr_dev->kccb.rtn_q);
+ pvr_device_safety_irq_init(pvr_dev);
+
pvr_dev->irq = platform_get_irq(plat_dev, 0);
if (pvr_dev->irq < 0)
return pvr_dev->irq;
@@ -207,6 +313,9 @@ pvr_device_irq_init(struct pvr_device *pvr_dev)
pvr_fw_irq_clear(pvr_dev);
pvr_fw_irq_enable(pvr_dev);
+ if (pvr_dev->has_safety_events)
+ pvr_device_safety_irq_clear(pvr_dev);
+
/*
* The ONESHOT flag ensures IRQs are masked while the thread handler is
* running.
diff --git a/drivers/gpu/drm/imagination/pvr_device.h b/drivers/gpu/drm/imagination/pvr_device.h
index 2dd8a8885fe07078896d669d822525fb2b7bab51..6c01d96657de6dc3904ef5ca28365f06cfe0f40b 100644
--- a/drivers/gpu/drm/imagination/pvr_device.h
+++ b/drivers/gpu/drm/imagination/pvr_device.h
@@ -308,6 +308,9 @@ struct pvr_device {
* struct pvr_file.
*/
spinlock_t ctx_list_lock;
+
+ /** @has_safety_events: Whether this device can raise safety events. */
+ bool has_safety_events;
};
/**
diff --git a/drivers/gpu/drm/imagination/pvr_fw.c b/drivers/gpu/drm/imagination/pvr_fw.c
index d09c4c68411627714c14dee5ed4e61b07baca1ba..555b5ca4a27de78ac092bf94c601d284abe41ea6 100644
--- a/drivers/gpu/drm/imagination/pvr_fw.c
+++ b/drivers/gpu/drm/imagination/pvr_fw.c
@@ -441,6 +441,9 @@ fw_runtime_cfg_init(void *cpu_ptr, void *priv)
runtime_cfg->active_pm_latency_persistant = true;
WARN_ON(PVR_FEATURE_VALUE(pvr_dev, num_clusters,
&runtime_cfg->default_dusts_num_init) != 0);
+
+ /* Keep watchdog timer disabled. */
+ runtime_cfg->wdg_period_us = 0;
}
static void
--
2.49.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v4 08/18] drm/imagination: Remove firmware enable_reg
2025-03-20 11:32 [PATCH v4 00/18] Imagination BXS-4-64 MC1 GPU support Matt Coster
` (6 preceding siblings ...)
2025-03-20 11:32 ` [PATCH v4 07/18] drm/imagination: Handle Rogue safety event IRQs Matt Coster
@ 2025-03-20 11:32 ` Matt Coster
2025-03-20 11:32 ` [PATCH v4 09/18] drm/imagination: Rename event_mask -> status_mask Matt Coster
` (9 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Matt Coster @ 2025-03-20 11:32 UTC (permalink / raw)
To: Frank Binns, Matt Coster, David Airlie, Simona Vetter,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Nishanth Menon,
Vignesh Raghavendra, Tero Kristo
Cc: dri-devel, devicetree, linux-kernel, linux-arm-kernel,
Randolph Sapp, Darren Etheridge, Michal Wilczynski, Alessio Belle,
Alexandru Dadu
After a previous commit ("drm/imagination: Mask GPU IRQs in threaded
handler"), this register is now only used to enable firmware interrupts at
start-of-day. This is, however, unnecessary since they are enabled by
default.
In addition, the soon-to-be-added RISC-V firmware processors do not have
an equivalent register.
Signed-off-by: Matt Coster <matt.coster@imgtec.com>
---
Changes in v4:
- None
- Link to v3: https://lore.kernel.org/r/20250310-sets-bxs-4-64-patch-v1-v3-8-143b3dbef02f@imgtec.com
Changes in v3:
- Reference a different commit removing use of enable/disable ops.
- Link to v2: https://lore.kernel.org/r/20241118-sets-bxs-4-64-patch-v1-v2-10-3fd45d9fb0cf@imgtec.com
Changes in v2:
- None
- Link to v1: https://lore.kernel.org/r/20241105-sets-bxs-4-64-patch-v1-v1-10-4ed30e865892@imgtec.com
---
drivers/gpu/drm/imagination/pvr_device.c | 1 -
drivers/gpu/drm/imagination/pvr_fw.h | 11 +----------
drivers/gpu/drm/imagination/pvr_fw_meta.c | 1 -
drivers/gpu/drm/imagination/pvr_fw_mips.c | 1 -
4 files changed, 1 insertion(+), 13 deletions(-)
diff --git a/drivers/gpu/drm/imagination/pvr_device.c b/drivers/gpu/drm/imagination/pvr_device.c
index a47dd1dd82432f1d66ff90aca26b7b264f4068df..1e488a30c7840466574c7fc3648ab93edfb46354 100644
--- a/drivers/gpu/drm/imagination/pvr_device.c
+++ b/drivers/gpu/drm/imagination/pvr_device.c
@@ -311,7 +311,6 @@ pvr_device_irq_init(struct pvr_device *pvr_dev)
/* Clear any pending events before requesting the IRQ line. */
pvr_fw_irq_clear(pvr_dev);
- pvr_fw_irq_enable(pvr_dev);
if (pvr_dev->has_safety_events)
pvr_device_safety_irq_clear(pvr_dev);
diff --git a/drivers/gpu/drm/imagination/pvr_fw.h b/drivers/gpu/drm/imagination/pvr_fw.h
index b7966bd574a924862b7877c175fa2b5d757d89db..29bae4bc244a243a6a95bcf838d924060cc043e2 100644
--- a/drivers/gpu/drm/imagination/pvr_fw.h
+++ b/drivers/gpu/drm/imagination/pvr_fw.h
@@ -188,9 +188,6 @@ struct pvr_fw_defs {
* processor backend in pvr_fw_funcs::init().
*/
struct {
- /** @enable_reg: FW interrupt enable register. */
- u32 enable_reg;
-
/** @status_reg: FW interrupt status register. */
u32 status_reg;
@@ -202,7 +199,7 @@ struct pvr_fw_defs {
*/
u32 clear_reg;
- /** @event_mask: Bitmask of events to listen for. */
+ /** @event_mask: Bitmask of events to listen for in the status_reg. */
u32 event_mask;
/** @clear_mask: Value to write to the clear_reg in order to clear FW IRQs. */
@@ -412,12 +409,6 @@ struct pvr_fw_device {
#define pvr_fw_irq_clear(pvr_dev) \
pvr_fw_irq_write_reg(pvr_dev, clear, (pvr_dev)->fw_dev.defs->irq.clear_mask)
-#define pvr_fw_irq_enable(pvr_dev) \
- pvr_fw_irq_write_reg(pvr_dev, enable, (pvr_dev)->fw_dev.defs->irq.event_mask)
-
-#define pvr_fw_irq_disable(pvr_dev) \
- pvr_fw_irq_write_reg(pvr_dev, enable, 0)
-
extern const struct pvr_fw_defs pvr_fw_defs_meta;
extern const struct pvr_fw_defs pvr_fw_defs_mips;
diff --git a/drivers/gpu/drm/imagination/pvr_fw_meta.c b/drivers/gpu/drm/imagination/pvr_fw_meta.c
index 6d13864851fc2e83bdaa94f16435b97841e5de94..a51eec867884b24767f23b3b34cd7029cb660f48 100644
--- a/drivers/gpu/drm/imagination/pvr_fw_meta.c
+++ b/drivers/gpu/drm/imagination/pvr_fw_meta.c
@@ -548,7 +548,6 @@ const struct pvr_fw_defs pvr_fw_defs_meta = {
.wrapper_init = pvr_meta_wrapper_init,
.has_fixed_data_addr = pvr_meta_has_fixed_data_addr,
.irq = {
- .enable_reg = ROGUE_CR_META_SP_MSLVIRQENABLE,
.status_reg = ROGUE_CR_META_SP_MSLVIRQSTATUS,
.clear_reg = ROGUE_CR_META_SP_MSLVIRQSTATUS,
.event_mask = ROGUE_CR_META_SP_MSLVIRQSTATUS_TRIGVECT2_EN,
diff --git a/drivers/gpu/drm/imagination/pvr_fw_mips.c b/drivers/gpu/drm/imagination/pvr_fw_mips.c
index 0bed0257e2ab75f66d8b8966b2ceac6342396fb5..c810a67eeecf1016064e76baf534e31a44c859b5 100644
--- a/drivers/gpu/drm/imagination/pvr_fw_mips.c
+++ b/drivers/gpu/drm/imagination/pvr_fw_mips.c
@@ -243,7 +243,6 @@ const struct pvr_fw_defs pvr_fw_defs_mips = {
.wrapper_init = pvr_mips_wrapper_init,
.has_fixed_data_addr = pvr_mips_has_fixed_data_addr,
.irq = {
- .enable_reg = ROGUE_CR_MIPS_WRAPPER_IRQ_ENABLE,
.status_reg = ROGUE_CR_MIPS_WRAPPER_IRQ_STATUS,
.clear_reg = ROGUE_CR_MIPS_WRAPPER_IRQ_CLEAR,
.event_mask = ROGUE_CR_MIPS_WRAPPER_IRQ_STATUS_EVENT_EN,
--
2.49.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v4 09/18] drm/imagination: Rename event_mask -> status_mask
2025-03-20 11:32 [PATCH v4 00/18] Imagination BXS-4-64 MC1 GPU support Matt Coster
` (7 preceding siblings ...)
2025-03-20 11:32 ` [PATCH v4 08/18] drm/imagination: Remove firmware enable_reg Matt Coster
@ 2025-03-20 11:32 ` Matt Coster
2025-03-20 11:32 ` [PATCH v4 10/18] drm/imagination: Make has_fixed_data_addr a value Matt Coster
` (8 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Matt Coster @ 2025-03-20 11:32 UTC (permalink / raw)
To: Frank Binns, Matt Coster, David Airlie, Simona Vetter,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Nishanth Menon,
Vignesh Raghavendra, Tero Kristo
Cc: dri-devel, devicetree, linux-kernel, linux-arm-kernel,
Randolph Sapp, Darren Etheridge, Michal Wilczynski, Alessio Belle,
Alexandru Dadu
Now that enable_reg isn't used, rename the previously shared event_mask to
status_mask since it's only used with status_reg.
Signed-off-by: Matt Coster <matt.coster@imgtec.com>
---
Changes in v4:
- None
- Link to v3: https://lore.kernel.org/r/20250310-sets-bxs-4-64-patch-v1-v3-9-143b3dbef02f@imgtec.com
Changes in v3:
- None
- Link to v2: https://lore.kernel.org/r/20241118-sets-bxs-4-64-patch-v1-v2-11-3fd45d9fb0cf@imgtec.com
Changes in v2:
- None
- Link to v1: https://lore.kernel.org/r/20241105-sets-bxs-4-64-patch-v1-v1-11-4ed30e865892@imgtec.com
---
drivers/gpu/drm/imagination/pvr_fw.h | 6 +++---
drivers/gpu/drm/imagination/pvr_fw_meta.c | 2 +-
drivers/gpu/drm/imagination/pvr_fw_mips.c | 2 +-
3 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/imagination/pvr_fw.h b/drivers/gpu/drm/imagination/pvr_fw.h
index 29bae4bc244a243a6a95bcf838d924060cc043e2..eead744835726712622d5aba9b3480fe264a089f 100644
--- a/drivers/gpu/drm/imagination/pvr_fw.h
+++ b/drivers/gpu/drm/imagination/pvr_fw.h
@@ -199,8 +199,8 @@ struct pvr_fw_defs {
*/
u32 clear_reg;
- /** @event_mask: Bitmask of events to listen for in the status_reg. */
- u32 event_mask;
+ /** @status_mask: Bitmask of events to listen for in the status_reg. */
+ u32 status_mask;
/** @clear_mask: Value to write to the clear_reg in order to clear FW IRQs. */
u32 clear_mask;
@@ -404,7 +404,7 @@ struct pvr_fw_device {
pvr_cr_write32((pvr_dev), (pvr_dev)->fw_dev.defs->irq.name ## _reg, value)
#define pvr_fw_irq_pending(pvr_dev) \
- (pvr_fw_irq_read_reg(pvr_dev, status) & (pvr_dev)->fw_dev.defs->irq.event_mask)
+ (pvr_fw_irq_read_reg(pvr_dev, status) & (pvr_dev)->fw_dev.defs->irq.status_mask)
#define pvr_fw_irq_clear(pvr_dev) \
pvr_fw_irq_write_reg(pvr_dev, clear, (pvr_dev)->fw_dev.defs->irq.clear_mask)
diff --git a/drivers/gpu/drm/imagination/pvr_fw_meta.c b/drivers/gpu/drm/imagination/pvr_fw_meta.c
index a51eec867884b24767f23b3b34cd7029cb660f48..6786e0153970691fa51ba3a0e62c00a46244a3a3 100644
--- a/drivers/gpu/drm/imagination/pvr_fw_meta.c
+++ b/drivers/gpu/drm/imagination/pvr_fw_meta.c
@@ -550,7 +550,7 @@ const struct pvr_fw_defs pvr_fw_defs_meta = {
.irq = {
.status_reg = ROGUE_CR_META_SP_MSLVIRQSTATUS,
.clear_reg = ROGUE_CR_META_SP_MSLVIRQSTATUS,
- .event_mask = ROGUE_CR_META_SP_MSLVIRQSTATUS_TRIGVECT2_EN,
+ .status_mask = ROGUE_CR_META_SP_MSLVIRQSTATUS_TRIGVECT2_EN,
.clear_mask = ROGUE_CR_META_SP_MSLVIRQSTATUS_TRIGVECT2_CLRMSK,
},
};
diff --git a/drivers/gpu/drm/imagination/pvr_fw_mips.c b/drivers/gpu/drm/imagination/pvr_fw_mips.c
index c810a67eeecf1016064e76baf534e31a44c859b5..f195c602bb112066e88210d0106cb5ffc0a9abc6 100644
--- a/drivers/gpu/drm/imagination/pvr_fw_mips.c
+++ b/drivers/gpu/drm/imagination/pvr_fw_mips.c
@@ -245,7 +245,7 @@ const struct pvr_fw_defs pvr_fw_defs_mips = {
.irq = {
.status_reg = ROGUE_CR_MIPS_WRAPPER_IRQ_STATUS,
.clear_reg = ROGUE_CR_MIPS_WRAPPER_IRQ_CLEAR,
- .event_mask = ROGUE_CR_MIPS_WRAPPER_IRQ_STATUS_EVENT_EN,
+ .status_mask = ROGUE_CR_MIPS_WRAPPER_IRQ_STATUS_EVENT_EN,
.clear_mask = ROGUE_CR_MIPS_WRAPPER_IRQ_CLEAR_EVENT_EN,
},
};
--
2.49.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v4 10/18] drm/imagination: Make has_fixed_data_addr a value
2025-03-20 11:32 [PATCH v4 00/18] Imagination BXS-4-64 MC1 GPU support Matt Coster
` (8 preceding siblings ...)
2025-03-20 11:32 ` [PATCH v4 09/18] drm/imagination: Rename event_mask -> status_mask Matt Coster
@ 2025-03-20 11:32 ` Matt Coster
2025-03-20 11:32 ` [PATCH v4 11/18] drm/imagination: Use a lookup table for fw defs Matt Coster
` (7 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Matt Coster @ 2025-03-20 11:32 UTC (permalink / raw)
To: Frank Binns, Matt Coster, David Airlie, Simona Vetter,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Nishanth Menon,
Vignesh Raghavendra, Tero Kristo
Cc: dri-devel, devicetree, linux-kernel, linux-arm-kernel,
Randolph Sapp, Darren Etheridge, Michal Wilczynski, Alessio Belle,
Alexandru Dadu
This is currently a callback function which takes no parameters; there's
no reason for this so let's make it a straightforward value in pvr_fw_defs.
Signed-off-by: Matt Coster <matt.coster@imgtec.com>
---
Changes in v4:
- None
- Link to v3: https://lore.kernel.org/r/20250310-sets-bxs-4-64-patch-v1-v3-10-143b3dbef02f@imgtec.com
Changes in v3:
- None
- Link to v2: https://lore.kernel.org/r/20241118-sets-bxs-4-64-patch-v1-v2-11-3fd45d9fb0cf@imgtec.com
Changes in v2:
- None
- Link to v1: https://lore.kernel.org/r/20241105-sets-bxs-4-64-patch-v1-v1-12-4ed30e865892@imgtec.com
---
drivers/gpu/drm/imagination/pvr_fw.c | 2 +-
drivers/gpu/drm/imagination/pvr_fw.h | 23 ++++++++---------------
drivers/gpu/drm/imagination/pvr_fw_meta.c | 8 +-------
drivers/gpu/drm/imagination/pvr_fw_mips.c | 8 +-------
4 files changed, 11 insertions(+), 30 deletions(-)
diff --git a/drivers/gpu/drm/imagination/pvr_fw.c b/drivers/gpu/drm/imagination/pvr_fw.c
index 555b5ca4a27de78ac092bf94c601d284abe41ea6..74ea83b5c1a5f1edd79d2f5ccf1c6b1b400524a9 100644
--- a/drivers/gpu/drm/imagination/pvr_fw.c
+++ b/drivers/gpu/drm/imagination/pvr_fw.c
@@ -666,7 +666,7 @@ pvr_fw_process(struct pvr_device *pvr_dev)
return PTR_ERR(fw_code_ptr);
}
- if (pvr_dev->fw_dev.defs->has_fixed_data_addr()) {
+ if (pvr_dev->fw_dev.defs->has_fixed_data_addr) {
u32 base_addr = private_data->base_addr & pvr_dev->fw_dev.fw_heap_info.offset_mask;
fw_data_ptr =
diff --git a/drivers/gpu/drm/imagination/pvr_fw.h b/drivers/gpu/drm/imagination/pvr_fw.h
index eead744835726712622d5aba9b3480fe264a089f..180d310074e3585c641e540a9e2576b5ab2a5705 100644
--- a/drivers/gpu/drm/imagination/pvr_fw.h
+++ b/drivers/gpu/drm/imagination/pvr_fw.h
@@ -166,21 +166,6 @@ struct pvr_fw_defs {
*/
int (*wrapper_init)(struct pvr_device *pvr_dev);
- /**
- * @has_fixed_data_addr:
- *
- * Called to check if firmware fixed data must be loaded at the address given by the
- * firmware layout table.
- *
- * This function is mandatory.
- *
- * Returns:
- * * %true if firmware fixed data must be loaded at the address given by the firmware
- * layout table.
- * * %false otherwise.
- */
- bool (*has_fixed_data_addr)(void);
-
/**
* @irq: FW Interrupt information.
*
@@ -205,6 +190,14 @@ struct pvr_fw_defs {
/** @clear_mask: Value to write to the clear_reg in order to clear FW IRQs. */
u32 clear_mask;
} irq;
+
+ /**
+ * @has_fixed_data_addr: Specify whether the firmware fixed data must be loaded at the
+ * address given by the firmware layout table.
+ *
+ * This value is mandatory.
+ */
+ bool has_fixed_data_addr;
};
/**
diff --git a/drivers/gpu/drm/imagination/pvr_fw_meta.c b/drivers/gpu/drm/imagination/pvr_fw_meta.c
index 6786e0153970691fa51ba3a0e62c00a46244a3a3..62ddfea6b7306784b979ce209bfdf4a9938f8984 100644
--- a/drivers/gpu/drm/imagination/pvr_fw_meta.c
+++ b/drivers/gpu/drm/imagination/pvr_fw_meta.c
@@ -533,12 +533,6 @@ pvr_meta_vm_unmap(struct pvr_device *pvr_dev, struct pvr_fw_object *fw_obj)
fw_obj->fw_mm_node.start, fw_obj->fw_mm_node.size);
}
-static bool
-pvr_meta_has_fixed_data_addr(void)
-{
- return false;
-}
-
const struct pvr_fw_defs pvr_fw_defs_meta = {
.init = pvr_meta_init,
.fw_process = pvr_meta_fw_process,
@@ -546,11 +540,11 @@ const struct pvr_fw_defs pvr_fw_defs_meta = {
.vm_unmap = pvr_meta_vm_unmap,
.get_fw_addr_with_offset = pvr_meta_get_fw_addr_with_offset,
.wrapper_init = pvr_meta_wrapper_init,
- .has_fixed_data_addr = pvr_meta_has_fixed_data_addr,
.irq = {
.status_reg = ROGUE_CR_META_SP_MSLVIRQSTATUS,
.clear_reg = ROGUE_CR_META_SP_MSLVIRQSTATUS,
.status_mask = ROGUE_CR_META_SP_MSLVIRQSTATUS_TRIGVECT2_EN,
.clear_mask = ROGUE_CR_META_SP_MSLVIRQSTATUS_TRIGVECT2_CLRMSK,
},
+ .has_fixed_data_addr = false,
};
diff --git a/drivers/gpu/drm/imagination/pvr_fw_mips.c b/drivers/gpu/drm/imagination/pvr_fw_mips.c
index f195c602bb112066e88210d0106cb5ffc0a9abc6..2c3172841886b70eb7a9992ec3851f18adcad8d5 100644
--- a/drivers/gpu/drm/imagination/pvr_fw_mips.c
+++ b/drivers/gpu/drm/imagination/pvr_fw_mips.c
@@ -227,12 +227,6 @@ pvr_mips_get_fw_addr_with_offset(struct pvr_fw_object *fw_obj, u32 offset)
ROGUE_FW_HEAP_MIPS_BASE;
}
-static bool
-pvr_mips_has_fixed_data_addr(void)
-{
- return true;
-}
-
const struct pvr_fw_defs pvr_fw_defs_mips = {
.init = pvr_mips_init,
.fini = pvr_mips_fini,
@@ -241,11 +235,11 @@ const struct pvr_fw_defs pvr_fw_defs_mips = {
.vm_unmap = pvr_vm_mips_unmap,
.get_fw_addr_with_offset = pvr_mips_get_fw_addr_with_offset,
.wrapper_init = pvr_mips_wrapper_init,
- .has_fixed_data_addr = pvr_mips_has_fixed_data_addr,
.irq = {
.status_reg = ROGUE_CR_MIPS_WRAPPER_IRQ_STATUS,
.clear_reg = ROGUE_CR_MIPS_WRAPPER_IRQ_CLEAR,
.status_mask = ROGUE_CR_MIPS_WRAPPER_IRQ_STATUS_EVENT_EN,
.clear_mask = ROGUE_CR_MIPS_WRAPPER_IRQ_CLEAR_EVENT_EN,
},
+ .has_fixed_data_addr = true,
};
--
2.49.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v4 11/18] drm/imagination: Use a lookup table for fw defs
2025-03-20 11:32 [PATCH v4 00/18] Imagination BXS-4-64 MC1 GPU support Matt Coster
` (9 preceding siblings ...)
2025-03-20 11:32 ` [PATCH v4 10/18] drm/imagination: Make has_fixed_data_addr a value Matt Coster
@ 2025-03-20 11:32 ` Matt Coster
2025-03-20 11:32 ` [PATCH v4 12/18] drm/imagination: Use callbacks for fw irq handling Matt Coster
` (6 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Matt Coster @ 2025-03-20 11:32 UTC (permalink / raw)
To: Frank Binns, Matt Coster, David Airlie, Simona Vetter,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Nishanth Menon,
Vignesh Raghavendra, Tero Kristo
Cc: dri-devel, devicetree, linux-kernel, linux-arm-kernel,
Randolph Sapp, Darren Etheridge, Michal Wilczynski, Alessio Belle,
Alexandru Dadu
With more than two firmware processor types, the if/else chain in
pvr_fw_init() gets a bit ridiculous. Use a static array indexed on
pvr_fw_processor_type (which is now a proper enum instead of #defines)
instead.
Signed-off-by: Matt Coster <matt.coster@imgtec.com>
---
Changes in v4:
- None
- Link to v3: https://lore.kernel.org/r/20250310-sets-bxs-4-64-patch-v1-v3-11-143b3dbef02f@imgtec.com
Changes in v3:
- None
- Link to v2: https://lore.kernel.org/r/20241118-sets-bxs-4-64-patch-v1-v2-13-3fd45d9fb0cf@imgtec.com
Changes in v2:
- None
- Link to v1: https://lore.kernel.org/r/20241105-sets-bxs-4-64-patch-v1-v1-13-4ed30e865892@imgtec.com
---
drivers/gpu/drm/imagination/pvr_device.h | 4 ----
drivers/gpu/drm/imagination/pvr_fw.c | 21 ++++++++++++++++-----
drivers/gpu/drm/imagination/pvr_fw.h | 7 +++++++
3 files changed, 23 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/imagination/pvr_device.h b/drivers/gpu/drm/imagination/pvr_device.h
index 6c01d96657de6dc3904ef5ca28365f06cfe0f40b..12bf0b9e5bfb48ef9e5ed9faa44e0896b7555f49 100644
--- a/drivers/gpu/drm/imagination/pvr_device.h
+++ b/drivers/gpu/drm/imagination/pvr_device.h
@@ -739,8 +739,4 @@ pvr_ioctl_union_padding_check(void *instance, size_t union_offset,
__union_size, __member_size); \
})
-#define PVR_FW_PROCESSOR_TYPE_META 0
-#define PVR_FW_PROCESSOR_TYPE_MIPS 1
-#define PVR_FW_PROCESSOR_TYPE_RISCV 2
-
#endif /* PVR_DEVICE_H */
diff --git a/drivers/gpu/drm/imagination/pvr_fw.c b/drivers/gpu/drm/imagination/pvr_fw.c
index 74ea83b5c1a5f1edd79d2f5ccf1c6b1b400524a9..a69c3c306a1c1de0a9587c003e1e03e4604cca81 100644
--- a/drivers/gpu/drm/imagination/pvr_fw.c
+++ b/drivers/gpu/drm/imagination/pvr_fw.c
@@ -942,16 +942,27 @@ pvr_fw_validate_init_device_info(struct pvr_device *pvr_dev)
int
pvr_fw_init(struct pvr_device *pvr_dev)
{
+ static const struct pvr_fw_defs *fw_defs[PVR_FW_PROCESSOR_TYPE_COUNT] = {
+ [PVR_FW_PROCESSOR_TYPE_META] = &pvr_fw_defs_meta,
+ [PVR_FW_PROCESSOR_TYPE_MIPS] = &pvr_fw_defs_mips,
+ [PVR_FW_PROCESSOR_TYPE_RISCV] = NULL,
+ };
+
u32 kccb_size_log2 = ROGUE_FWIF_KCCB_NUMCMDS_LOG2_DEFAULT;
u32 kccb_rtn_size = (1 << kccb_size_log2) * sizeof(*pvr_dev->kccb.rtn);
struct pvr_fw_device *fw_dev = &pvr_dev->fw_dev;
int err;
- if (fw_dev->processor_type == PVR_FW_PROCESSOR_TYPE_META)
- fw_dev->defs = &pvr_fw_defs_meta;
- else if (fw_dev->processor_type == PVR_FW_PROCESSOR_TYPE_MIPS)
- fw_dev->defs = &pvr_fw_defs_mips;
- else
+ if (fw_dev->processor_type >= PVR_FW_PROCESSOR_TYPE_COUNT)
+ return -EINVAL;
+
+ fw_dev->defs = fw_defs[fw_dev->processor_type];
+
+ /*
+ * Not all firmware processor types are currently supported.
+ * Once they are, this check can be removed.
+ */
+ if (!fw_dev->defs)
return -EINVAL;
err = fw_dev->defs->init(pvr_dev);
diff --git a/drivers/gpu/drm/imagination/pvr_fw.h b/drivers/gpu/drm/imagination/pvr_fw.h
index 180d310074e3585c641e540a9e2576b5ab2a5705..88ad713468ce3a1ee459b04dde5363c24791a4f1 100644
--- a/drivers/gpu/drm/imagination/pvr_fw.h
+++ b/drivers/gpu/drm/imagination/pvr_fw.h
@@ -402,6 +402,13 @@ struct pvr_fw_device {
#define pvr_fw_irq_clear(pvr_dev) \
pvr_fw_irq_write_reg(pvr_dev, clear, (pvr_dev)->fw_dev.defs->irq.clear_mask)
+enum pvr_fw_processor_type {
+ PVR_FW_PROCESSOR_TYPE_META = 0,
+ PVR_FW_PROCESSOR_TYPE_MIPS,
+ PVR_FW_PROCESSOR_TYPE_RISCV,
+ PVR_FW_PROCESSOR_TYPE_COUNT,
+};
+
extern const struct pvr_fw_defs pvr_fw_defs_meta;
extern const struct pvr_fw_defs pvr_fw_defs_mips;
--
2.49.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v4 12/18] drm/imagination: Use callbacks for fw irq handling
2025-03-20 11:32 [PATCH v4 00/18] Imagination BXS-4-64 MC1 GPU support Matt Coster
` (10 preceding siblings ...)
2025-03-20 11:32 ` [PATCH v4 11/18] drm/imagination: Use a lookup table for fw defs Matt Coster
@ 2025-03-20 11:32 ` Matt Coster
2025-03-20 11:32 ` [PATCH v4 13/18] drm/imagination: Move ELF fw utils to common file Matt Coster
` (5 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Matt Coster @ 2025-03-20 11:32 UTC (permalink / raw)
To: Frank Binns, Matt Coster, David Airlie, Simona Vetter,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Nishanth Menon,
Vignesh Raghavendra, Tero Kristo
Cc: dri-devel, devicetree, linux-kernel, linux-arm-kernel,
Randolph Sapp, Darren Etheridge, Michal Wilczynski, Alessio Belle,
Alexandru Dadu
This allows for more versatility in checking and clearing firmware
registers used for interrupt handling.
Signed-off-by: Matt Coster <matt.coster@imgtec.com>
---
Changes in v4:
- None
- Link to v3: https://lore.kernel.org/r/20250310-sets-bxs-4-64-patch-v1-v3-12-143b3dbef02f@imgtec.com
Changes in v3:
- None
- Link to v2: https://lore.kernel.org/r/20241118-sets-bxs-4-64-patch-v1-v2-14-3fd45d9fb0cf@imgtec.com
Changes in v2:
- None
- Link to v1: https://lore.kernel.org/r/20241105-sets-bxs-4-64-patch-v1-v1-14-4ed30e865892@imgtec.com
---
drivers/gpu/drm/imagination/pvr_device.h | 18 +++++++++++++
drivers/gpu/drm/imagination/pvr_fw.h | 45 +++++++++----------------------
drivers/gpu/drm/imagination/pvr_fw_meta.c | 22 ++++++++++-----
drivers/gpu/drm/imagination/pvr_fw_mips.c | 22 ++++++++++-----
4 files changed, 63 insertions(+), 44 deletions(-)
diff --git a/drivers/gpu/drm/imagination/pvr_device.h b/drivers/gpu/drm/imagination/pvr_device.h
index 12bf0b9e5bfb48ef9e5ed9faa44e0896b7555f49..eb5da8c7040fc9e9751f433279cb0c92fd4d1336 100644
--- a/drivers/gpu/drm/imagination/pvr_device.h
+++ b/drivers/gpu/drm/imagination/pvr_device.h
@@ -739,4 +739,22 @@ pvr_ioctl_union_padding_check(void *instance, size_t union_offset,
__union_size, __member_size); \
})
+/*
+ * These utility functions should more properly be placed in pvr_fw.h, but that
+ * would cause a dependency cycle between that header and this one. Since
+ * they're primarily used in pvr_device.c, let's put them in here for now.
+ */
+
+static __always_inline bool
+pvr_fw_irq_pending(struct pvr_device *pvr_dev)
+{
+ return pvr_dev->fw_dev.defs->irq_pending(pvr_dev);
+}
+
+static __always_inline void
+pvr_fw_irq_clear(struct pvr_device *pvr_dev)
+{
+ pvr_dev->fw_dev.defs->irq_clear(pvr_dev);
+}
+
#endif /* PVR_DEVICE_H */
diff --git a/drivers/gpu/drm/imagination/pvr_fw.h b/drivers/gpu/drm/imagination/pvr_fw.h
index 88ad713468ce3a1ee459b04dde5363c24791a4f1..ab69f40a7fbc6304171f16dd16d825a68b0362a5 100644
--- a/drivers/gpu/drm/imagination/pvr_fw.h
+++ b/drivers/gpu/drm/imagination/pvr_fw.h
@@ -167,29 +167,22 @@ struct pvr_fw_defs {
int (*wrapper_init)(struct pvr_device *pvr_dev);
/**
- * @irq: FW Interrupt information.
+ * @irq_pending: Check interrupt status register for pending interrupts.
*
- * Those are processor dependent, and should be initialized by the
- * processor backend in pvr_fw_funcs::init().
+ * @pvr_dev: Target PowerVR device.
+ *
+ * This function is mandatory.
*/
- struct {
- /** @status_reg: FW interrupt status register. */
- u32 status_reg;
+ bool (*irq_pending)(struct pvr_device *pvr_dev);
- /**
- * @clear_reg: FW interrupt clear register.
- *
- * If @status_reg == @clear_reg, we clear by write a bit to zero,
- * otherwise we clear by writing a bit to one.
- */
- u32 clear_reg;
-
- /** @status_mask: Bitmask of events to listen for in the status_reg. */
- u32 status_mask;
-
- /** @clear_mask: Value to write to the clear_reg in order to clear FW IRQs. */
- u32 clear_mask;
- } irq;
+ /**
+ * @irq_clear: Clear pending interrupts.
+ *
+ * @pvr_dev: Target PowerVR device.
+ *
+ * This function is mandatory.
+ */
+ void (*irq_clear)(struct pvr_device *pvr_dev);
/**
* @has_fixed_data_addr: Specify whether the firmware fixed data must be loaded at the
@@ -390,18 +383,6 @@ struct pvr_fw_device {
} fw_objs;
};
-#define pvr_fw_irq_read_reg(pvr_dev, name) \
- pvr_cr_read32((pvr_dev), (pvr_dev)->fw_dev.defs->irq.name ## _reg)
-
-#define pvr_fw_irq_write_reg(pvr_dev, name, value) \
- pvr_cr_write32((pvr_dev), (pvr_dev)->fw_dev.defs->irq.name ## _reg, value)
-
-#define pvr_fw_irq_pending(pvr_dev) \
- (pvr_fw_irq_read_reg(pvr_dev, status) & (pvr_dev)->fw_dev.defs->irq.status_mask)
-
-#define pvr_fw_irq_clear(pvr_dev) \
- pvr_fw_irq_write_reg(pvr_dev, clear, (pvr_dev)->fw_dev.defs->irq.clear_mask)
-
enum pvr_fw_processor_type {
PVR_FW_PROCESSOR_TYPE_META = 0,
PVR_FW_PROCESSOR_TYPE_MIPS,
diff --git a/drivers/gpu/drm/imagination/pvr_fw_meta.c b/drivers/gpu/drm/imagination/pvr_fw_meta.c
index 62ddfea6b7306784b979ce209bfdf4a9938f8984..d72e0eae9e4b16cb31c48797ffcf5138d2728862 100644
--- a/drivers/gpu/drm/imagination/pvr_fw_meta.c
+++ b/drivers/gpu/drm/imagination/pvr_fw_meta.c
@@ -533,6 +533,20 @@ pvr_meta_vm_unmap(struct pvr_device *pvr_dev, struct pvr_fw_object *fw_obj)
fw_obj->fw_mm_node.start, fw_obj->fw_mm_node.size);
}
+static bool
+pvr_meta_irq_pending(struct pvr_device *pvr_dev)
+{
+ return pvr_cr_read32(pvr_dev, ROGUE_CR_META_SP_MSLVIRQSTATUS) &
+ ROGUE_CR_META_SP_MSLVIRQSTATUS_TRIGVECT2_EN;
+}
+
+static void
+pvr_meta_irq_clear(struct pvr_device *pvr_dev)
+{
+ pvr_cr_write32(pvr_dev, ROGUE_CR_META_SP_MSLVIRQSTATUS,
+ ROGUE_CR_META_SP_MSLVIRQSTATUS_TRIGVECT2_CLRMSK);
+}
+
const struct pvr_fw_defs pvr_fw_defs_meta = {
.init = pvr_meta_init,
.fw_process = pvr_meta_fw_process,
@@ -540,11 +554,7 @@ const struct pvr_fw_defs pvr_fw_defs_meta = {
.vm_unmap = pvr_meta_vm_unmap,
.get_fw_addr_with_offset = pvr_meta_get_fw_addr_with_offset,
.wrapper_init = pvr_meta_wrapper_init,
- .irq = {
- .status_reg = ROGUE_CR_META_SP_MSLVIRQSTATUS,
- .clear_reg = ROGUE_CR_META_SP_MSLVIRQSTATUS,
- .status_mask = ROGUE_CR_META_SP_MSLVIRQSTATUS_TRIGVECT2_EN,
- .clear_mask = ROGUE_CR_META_SP_MSLVIRQSTATUS_TRIGVECT2_CLRMSK,
- },
+ .irq_pending = pvr_meta_irq_pending,
+ .irq_clear = pvr_meta_irq_clear,
.has_fixed_data_addr = false,
};
diff --git a/drivers/gpu/drm/imagination/pvr_fw_mips.c b/drivers/gpu/drm/imagination/pvr_fw_mips.c
index 2c3172841886b70eb7a9992ec3851f18adcad8d5..524a9bd0a20b64c509f5708cc61d93b4c864b835 100644
--- a/drivers/gpu/drm/imagination/pvr_fw_mips.c
+++ b/drivers/gpu/drm/imagination/pvr_fw_mips.c
@@ -227,6 +227,20 @@ pvr_mips_get_fw_addr_with_offset(struct pvr_fw_object *fw_obj, u32 offset)
ROGUE_FW_HEAP_MIPS_BASE;
}
+static bool
+pvr_mips_irq_pending(struct pvr_device *pvr_dev)
+{
+ return pvr_cr_read32(pvr_dev, ROGUE_CR_MIPS_WRAPPER_IRQ_STATUS) &
+ ROGUE_CR_MIPS_WRAPPER_IRQ_STATUS_EVENT_EN;
+}
+
+static void
+pvr_mips_irq_clear(struct pvr_device *pvr_dev)
+{
+ pvr_cr_write32(pvr_dev, ROGUE_CR_MIPS_WRAPPER_IRQ_CLEAR,
+ ROGUE_CR_MIPS_WRAPPER_IRQ_CLEAR_EVENT_EN);
+}
+
const struct pvr_fw_defs pvr_fw_defs_mips = {
.init = pvr_mips_init,
.fini = pvr_mips_fini,
@@ -235,11 +249,7 @@ const struct pvr_fw_defs pvr_fw_defs_mips = {
.vm_unmap = pvr_vm_mips_unmap,
.get_fw_addr_with_offset = pvr_mips_get_fw_addr_with_offset,
.wrapper_init = pvr_mips_wrapper_init,
- .irq = {
- .status_reg = ROGUE_CR_MIPS_WRAPPER_IRQ_STATUS,
- .clear_reg = ROGUE_CR_MIPS_WRAPPER_IRQ_CLEAR,
- .status_mask = ROGUE_CR_MIPS_WRAPPER_IRQ_STATUS_EVENT_EN,
- .clear_mask = ROGUE_CR_MIPS_WRAPPER_IRQ_CLEAR_EVENT_EN,
- },
+ .irq_pending = pvr_mips_irq_pending,
+ .irq_clear = pvr_mips_irq_clear,
.has_fixed_data_addr = true,
};
--
2.49.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v4 13/18] drm/imagination: Move ELF fw utils to common file
2025-03-20 11:32 [PATCH v4 00/18] Imagination BXS-4-64 MC1 GPU support Matt Coster
` (11 preceding siblings ...)
2025-03-20 11:32 ` [PATCH v4 12/18] drm/imagination: Use callbacks for fw irq handling Matt Coster
@ 2025-03-20 11:32 ` Matt Coster
2025-03-20 11:32 ` [PATCH v4 14/18] drm/imagination: Add RISC-V firmware processor support Matt Coster
` (4 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Matt Coster @ 2025-03-20 11:32 UTC (permalink / raw)
To: Frank Binns, Matt Coster, David Airlie, Simona Vetter,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Nishanth Menon,
Vignesh Raghavendra, Tero Kristo
Cc: dri-devel, devicetree, linux-kernel, linux-arm-kernel,
Randolph Sapp, Darren Etheridge, Michal Wilczynski, Alessio Belle,
Alexandru Dadu
Currently only MIPS firmware processors use ELF-formatted firmware. When
adding support for RISC-V firmware processors, it will be useful to have
ELF handling functions ready to go.
Signed-off-by: Matt Coster <matt.coster@imgtec.com>
---
Changes in v4:
- None
- Link to v3: https://lore.kernel.org/r/20250310-sets-bxs-4-64-patch-v1-v3-13-143b3dbef02f@imgtec.com
Changes in v3:
- None
- Link to v2: https://lore.kernel.org/r/20241118-sets-bxs-4-64-patch-v1-v2-16-3fd45d9fb0cf@imgtec.com
Changes in v2:
- None
- Link to v1: https://lore.kernel.org/r/20241105-sets-bxs-4-64-patch-v1-v1-16-4ed30e865892@imgtec.com
---
drivers/gpu/drm/imagination/Makefile | 1 +
drivers/gpu/drm/imagination/pvr_fw.h | 5 +++
drivers/gpu/drm/imagination/pvr_fw_mips.c | 59 +--------------------------
drivers/gpu/drm/imagination/pvr_fw_util.c | 67 +++++++++++++++++++++++++++++++
4 files changed, 75 insertions(+), 57 deletions(-)
diff --git a/drivers/gpu/drm/imagination/Makefile b/drivers/gpu/drm/imagination/Makefile
index 9bc6a3884c2239e44265f3cdebee149841b270de..077e4762c7c383b6e339da1584c3865d830ef8d6 100644
--- a/drivers/gpu/drm/imagination/Makefile
+++ b/drivers/gpu/drm/imagination/Makefile
@@ -16,6 +16,7 @@ powervr-y := \
pvr_fw_mips.o \
pvr_fw_startstop.o \
pvr_fw_trace.o \
+ pvr_fw_util.o \
pvr_gem.o \
pvr_hwrt.o \
pvr_job.o \
diff --git a/drivers/gpu/drm/imagination/pvr_fw.h b/drivers/gpu/drm/imagination/pvr_fw.h
index ab69f40a7fbc6304171f16dd16d825a68b0362a5..e120eae06bf78633b5bae79a77adac63aa5e06d3 100644
--- a/drivers/gpu/drm/imagination/pvr_fw.h
+++ b/drivers/gpu/drm/imagination/pvr_fw.h
@@ -478,4 +478,9 @@ pvr_fw_object_get_fw_addr(struct pvr_fw_object *fw_obj, u32 *fw_addr_out)
pvr_fw_object_get_fw_addr_offset(fw_obj, 0, fw_addr_out);
}
+/* Util functions defined in pvr_fw_util.c. These are intended for use in pvr_fw_<arch>.c files. */
+int
+pvr_fw_process_elf_command_stream(struct pvr_device *pvr_dev, const u8 *fw, u8 *fw_code_ptr,
+ u8 *fw_data_ptr, u8 *fw_core_code_ptr, u8 *fw_core_data_ptr);
+
#endif /* PVR_FW_H */
diff --git a/drivers/gpu/drm/imagination/pvr_fw_mips.c b/drivers/gpu/drm/imagination/pvr_fw_mips.c
index 524a9bd0a20b64c509f5708cc61d93b4c864b835..7f341ceb0661c61ac059654faeec91e149036467 100644
--- a/drivers/gpu/drm/imagination/pvr_fw_mips.c
+++ b/drivers/gpu/drm/imagination/pvr_fw_mips.c
@@ -8,7 +8,6 @@
#include "pvr_rogue_mips.h"
#include "pvr_vm_mips.h"
-#include <linux/elf.h>
#include <linux/err.h>
#include <linux/types.h>
@@ -16,60 +15,6 @@
#define ROGUE_FW_HEAP_MIPS_SHIFT 24 /* 16 MB */
#define ROGUE_FW_HEAP_MIPS_RESERVED_SIZE SZ_1M
-/**
- * process_elf_command_stream() - Process ELF firmware image and populate
- * firmware sections
- * @pvr_dev: Device pointer.
- * @fw: Pointer to firmware image.
- * @fw_code_ptr: Pointer to FW code section.
- * @fw_data_ptr: Pointer to FW data section.
- * @fw_core_code_ptr: Pointer to FW coremem code section.
- * @fw_core_data_ptr: Pointer to FW coremem data section.
- *
- * Returns :
- * * 0 on success, or
- * * -EINVAL on any error in ELF command stream.
- */
-static int
-process_elf_command_stream(struct pvr_device *pvr_dev, const u8 *fw, u8 *fw_code_ptr,
- u8 *fw_data_ptr, u8 *fw_core_code_ptr, u8 *fw_core_data_ptr)
-{
- struct elf32_hdr *header = (struct elf32_hdr *)fw;
- struct elf32_phdr *program_header = (struct elf32_phdr *)(fw + header->e_phoff);
- struct drm_device *drm_dev = from_pvr_device(pvr_dev);
- u32 entry;
- int err;
-
- for (entry = 0; entry < header->e_phnum; entry++, program_header++) {
- void *write_addr;
-
- /* Only consider loadable entries in the ELF segment table */
- if (program_header->p_type != PT_LOAD)
- continue;
-
- err = pvr_fw_find_mmu_segment(pvr_dev, program_header->p_vaddr,
- program_header->p_memsz, fw_code_ptr, fw_data_ptr,
- fw_core_code_ptr, fw_core_data_ptr, &write_addr);
- if (err) {
- drm_err(drm_dev,
- "Addr 0x%x (size: %d) not found in any firmware segment",
- program_header->p_vaddr, program_header->p_memsz);
- return err;
- }
-
- /* Write to FW allocation only if available */
- if (write_addr) {
- memcpy(write_addr, fw + program_header->p_offset,
- program_header->p_filesz);
-
- memset((u8 *)write_addr + program_header->p_filesz, 0,
- program_header->p_memsz - program_header->p_filesz);
- }
- }
-
- return 0;
-}
-
static int
pvr_mips_init(struct pvr_device *pvr_dev)
{
@@ -100,8 +45,8 @@ pvr_mips_fw_process(struct pvr_device *pvr_dev, const u8 *fw,
u32 page_nr;
int err;
- err = process_elf_command_stream(pvr_dev, fw, fw_code_ptr, fw_data_ptr, fw_core_code_ptr,
- fw_core_data_ptr);
+ err = pvr_fw_process_elf_command_stream(pvr_dev, fw, fw_code_ptr, fw_data_ptr,
+ fw_core_code_ptr, fw_core_data_ptr);
if (err)
return err;
diff --git a/drivers/gpu/drm/imagination/pvr_fw_util.c b/drivers/gpu/drm/imagination/pvr_fw_util.c
new file mode 100644
index 0000000000000000000000000000000000000000..7bc8a5c48e9b0eed2045607ab2cfed80a60a32b5
--- /dev/null
+++ b/drivers/gpu/drm/imagination/pvr_fw_util.c
@@ -0,0 +1,67 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/* Copyright (c) 2024 Imagination Technologies Ltd. */
+
+#include "pvr_device.h"
+#include "pvr_fw.h"
+
+#include <drm/drm_device.h>
+#include <drm/drm_print.h>
+
+#include <linux/elf.h>
+#include <linux/string.h>
+#include <linux/types.h>
+
+/**
+ * pvr_fw_process_elf_command_stream() - Process ELF firmware image and populate
+ * firmware sections
+ * @pvr_dev: Device pointer.
+ * @fw: Pointer to firmware image.
+ * @fw_code_ptr: Pointer to FW code section.
+ * @fw_data_ptr: Pointer to FW data section.
+ * @fw_core_code_ptr: Pointer to FW coremem code section.
+ * @fw_core_data_ptr: Pointer to FW coremem data section.
+ *
+ * Returns :
+ * * 0 on success, or
+ * * -EINVAL on any error in ELF command stream.
+ */
+int
+pvr_fw_process_elf_command_stream(struct pvr_device *pvr_dev, const u8 *fw,
+ u8 *fw_code_ptr, u8 *fw_data_ptr,
+ u8 *fw_core_code_ptr, u8 *fw_core_data_ptr)
+{
+ struct elf32_hdr *header = (struct elf32_hdr *)fw;
+ struct elf32_phdr *program_header = (struct elf32_phdr *)(fw + header->e_phoff);
+ struct drm_device *drm_dev = from_pvr_device(pvr_dev);
+ u32 entry;
+ int err;
+
+ for (entry = 0; entry < header->e_phnum; entry++, program_header++) {
+ void *write_addr;
+
+ /* Only consider loadable entries in the ELF segment table */
+ if (program_header->p_type != PT_LOAD)
+ continue;
+
+ err = pvr_fw_find_mmu_segment(pvr_dev, program_header->p_vaddr,
+ program_header->p_memsz, fw_code_ptr, fw_data_ptr,
+ fw_core_code_ptr, fw_core_data_ptr, &write_addr);
+ if (err) {
+ drm_err(drm_dev,
+ "Addr 0x%x (size: %d) not found in any firmware segment",
+ program_header->p_vaddr, program_header->p_memsz);
+ return err;
+ }
+
+ /* Write to FW allocation only if available */
+ if (write_addr) {
+ memcpy(write_addr, fw + program_header->p_offset,
+ program_header->p_filesz);
+
+ memset((u8 *)write_addr + program_header->p_filesz, 0,
+ program_header->p_memsz - program_header->p_filesz);
+ }
+ }
+
+ return 0;
+}
--
2.49.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v4 14/18] drm/imagination: Add RISC-V firmware processor support
2025-03-20 11:32 [PATCH v4 00/18] Imagination BXS-4-64 MC1 GPU support Matt Coster
` (12 preceding siblings ...)
2025-03-20 11:32 ` [PATCH v4 13/18] drm/imagination: Move ELF fw utils to common file Matt Coster
@ 2025-03-20 11:32 ` Matt Coster
2025-03-20 11:32 ` [PATCH v4 15/18] drm/imagination: Use cached memory with dma_coherent Matt Coster
` (3 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Matt Coster @ 2025-03-20 11:32 UTC (permalink / raw)
To: Frank Binns, Matt Coster, David Airlie, Simona Vetter,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Nishanth Menon,
Vignesh Raghavendra, Tero Kristo
Cc: dri-devel, devicetree, linux-kernel, linux-arm-kernel,
Randolph Sapp, Darren Etheridge, Michal Wilczynski, Alessio Belle,
Alexandru Dadu, Sarah Walker
From: Sarah Walker <sarah.walker@imgtec.com>
Newer PowerVR GPUs (such as the BXS-4-64 MC1) use a RISC-V firmware
processor instead of the previous MIPS or META.
The current version of this patch depends on a patch[1] which exists in
drm-misc-fixes, but has not yet made it back to drm-misc-next (the
target of this patch). That patch adds the function pvr_vm_unmap_obj()
which is used here.
[1]: https://lore.kernel.org/r/20250226-hold-drm_gem_gpuva-lock-for-unmap-v2-1-3fdacded227f@imgtec.com
Signed-off-by: Sarah Walker <sarah.walker@imgtec.com>
Signed-off-by: Matt Coster <matt.coster@imgtec.com>
---
Changes in v4:
- Use pvr_vm_unmap_obj() in pvr_riscv_vm_unmap()
- Fix formatting of pvr_riscv_fw_process() signature
- Link to v3: https://lore.kernel.org/r/20250310-sets-bxs-4-64-patch-v1-v3-14-143b3dbef02f@imgtec.com
Changes in v3:
- Don't enable debug module
- Link to v2: https://lore.kernel.org/r/20241118-sets-bxs-4-64-patch-v1-v2-17-3fd45d9fb0cf@imgtec.com
Changes in v2:
- None
- Link to v1: https://lore.kernel.org/r/20241105-sets-bxs-4-64-patch-v1-v1-17-4ed30e865892@imgtec.com
---
drivers/gpu/drm/imagination/Makefile | 1 +
drivers/gpu/drm/imagination/pvr_fw.c | 18 +--
drivers/gpu/drm/imagination/pvr_fw.h | 10 ++
drivers/gpu/drm/imagination/pvr_fw_riscv.c | 165 +++++++++++++++++++++++++
drivers/gpu/drm/imagination/pvr_fw_startstop.c | 17 +++
drivers/gpu/drm/imagination/pvr_rogue_riscv.h | 41 ++++++
6 files changed, 244 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/imagination/Makefile b/drivers/gpu/drm/imagination/Makefile
index 077e4762c7c383b6e339da1584c3865d830ef8d6..d748ad9d62e092ed7c3d772214ccd327818d507f 100644
--- a/drivers/gpu/drm/imagination/Makefile
+++ b/drivers/gpu/drm/imagination/Makefile
@@ -14,6 +14,7 @@ powervr-y := \
pvr_fw.o \
pvr_fw_meta.o \
pvr_fw_mips.o \
+ pvr_fw_riscv.o \
pvr_fw_startstop.o \
pvr_fw_trace.o \
pvr_fw_util.o \
diff --git a/drivers/gpu/drm/imagination/pvr_fw.c b/drivers/gpu/drm/imagination/pvr_fw.c
index a69c3c306a1c1de0a9587c003e1e03e4604cca81..b1379ae46efd8139663c44aa1c3c565908b15aad 100644
--- a/drivers/gpu/drm/imagination/pvr_fw.c
+++ b/drivers/gpu/drm/imagination/pvr_fw.c
@@ -945,7 +945,7 @@ pvr_fw_init(struct pvr_device *pvr_dev)
static const struct pvr_fw_defs *fw_defs[PVR_FW_PROCESSOR_TYPE_COUNT] = {
[PVR_FW_PROCESSOR_TYPE_META] = &pvr_fw_defs_meta,
[PVR_FW_PROCESSOR_TYPE_MIPS] = &pvr_fw_defs_mips,
- [PVR_FW_PROCESSOR_TYPE_RISCV] = NULL,
+ [PVR_FW_PROCESSOR_TYPE_RISCV] = &pvr_fw_defs_riscv,
};
u32 kccb_size_log2 = ROGUE_FWIF_KCCB_NUMCMDS_LOG2_DEFAULT;
@@ -958,13 +958,6 @@ pvr_fw_init(struct pvr_device *pvr_dev)
fw_dev->defs = fw_defs[fw_dev->processor_type];
- /*
- * Not all firmware processor types are currently supported.
- * Once they are, this check can be removed.
- */
- if (!fw_dev->defs)
- return -EINVAL;
-
err = fw_dev->defs->init(pvr_dev);
if (err)
return err;
@@ -1470,6 +1463,15 @@ void pvr_fw_object_get_fw_addr_offset(struct pvr_fw_object *fw_obj, u32 offset,
*fw_addr_out = pvr_dev->fw_dev.defs->get_fw_addr_with_offset(fw_obj, offset);
}
+u64
+pvr_fw_obj_get_gpu_addr(struct pvr_fw_object *fw_obj)
+{
+ struct pvr_device *pvr_dev = to_pvr_device(gem_from_pvr_gem(fw_obj->gem)->dev);
+ struct pvr_fw_device *fw_dev = &pvr_dev->fw_dev;
+
+ return fw_dev->fw_heap_info.gpu_addr + fw_obj->fw_addr_offset;
+}
+
/*
* pvr_fw_hard_reset() - Re-initialise the FW code and data segments, and reset all global FW
* structures
diff --git a/drivers/gpu/drm/imagination/pvr_fw.h b/drivers/gpu/drm/imagination/pvr_fw.h
index e120eae06bf78633b5bae79a77adac63aa5e06d3..1404dd492d7cd82d62dd407a780efcae34d9bf2d 100644
--- a/drivers/gpu/drm/imagination/pvr_fw.h
+++ b/drivers/gpu/drm/imagination/pvr_fw.h
@@ -392,6 +392,7 @@ enum pvr_fw_processor_type {
extern const struct pvr_fw_defs pvr_fw_defs_meta;
extern const struct pvr_fw_defs pvr_fw_defs_mips;
+extern const struct pvr_fw_defs pvr_fw_defs_riscv;
int pvr_fw_validate_init_device_info(struct pvr_device *pvr_dev);
int pvr_fw_init(struct pvr_device *pvr_dev);
@@ -478,6 +479,15 @@ pvr_fw_object_get_fw_addr(struct pvr_fw_object *fw_obj, u32 *fw_addr_out)
pvr_fw_object_get_fw_addr_offset(fw_obj, 0, fw_addr_out);
}
+u64
+pvr_fw_obj_get_gpu_addr(struct pvr_fw_object *fw_obj);
+
+static __always_inline size_t
+pvr_fw_obj_get_object_size(struct pvr_fw_object *fw_obj)
+{
+ return pvr_gem_object_size(fw_obj->gem);
+}
+
/* Util functions defined in pvr_fw_util.c. These are intended for use in pvr_fw_<arch>.c files. */
int
pvr_fw_process_elf_command_stream(struct pvr_device *pvr_dev, const u8 *fw, u8 *fw_code_ptr,
diff --git a/drivers/gpu/drm/imagination/pvr_fw_riscv.c b/drivers/gpu/drm/imagination/pvr_fw_riscv.c
new file mode 100644
index 0000000000000000000000000000000000000000..fc13d483be9a3edd97cad3850e4edf312d5b16b6
--- /dev/null
+++ b/drivers/gpu/drm/imagination/pvr_fw_riscv.c
@@ -0,0 +1,165 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
+/* Copyright (c) 2024 Imagination Technologies Ltd. */
+
+#include "pvr_device.h"
+#include "pvr_fw.h"
+#include "pvr_fw_info.h"
+#include "pvr_fw_mips.h"
+#include "pvr_gem.h"
+#include "pvr_rogue_cr_defs.h"
+#include "pvr_rogue_riscv.h"
+#include "pvr_vm.h"
+
+#include <linux/compiler.h>
+#include <linux/delay.h>
+#include <linux/firmware.h>
+#include <linux/ktime.h>
+#include <linux/types.h>
+
+#define ROGUE_FW_HEAP_RISCV_SHIFT 25 /* 32 MB */
+#define ROGUE_FW_HEAP_RISCV_SIZE (1u << ROGUE_FW_HEAP_RISCV_SHIFT)
+
+static int
+pvr_riscv_wrapper_init(struct pvr_device *pvr_dev)
+{
+ const u64 common_opts =
+ ((u64)(ROGUE_FW_HEAP_RISCV_SIZE >> FWCORE_ADDR_REMAP_CONFIG0_SIZE_ALIGNSHIFT)
+ << ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG0_SIZE_SHIFT) |
+ ((u64)MMU_CONTEXT_MAPPING_FWPRIV
+ << FWCORE_ADDR_REMAP_CONFIG0_MMU_CONTEXT_SHIFT);
+
+ u64 code_addr = pvr_fw_obj_get_gpu_addr(pvr_dev->fw_dev.mem.code_obj);
+ u64 data_addr = pvr_fw_obj_get_gpu_addr(pvr_dev->fw_dev.mem.data_obj);
+
+ /* This condition allows us to OR the addresses into the register directly. */
+ static_assert(ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG1_DEVVADDR_SHIFT ==
+ ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG1_DEVVADDR_ALIGNSHIFT);
+
+ WARN_ON(code_addr & ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG1_DEVVADDR_CLRMSK);
+ WARN_ON(data_addr & ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG1_DEVVADDR_CLRMSK);
+
+ pvr_cr_write64(pvr_dev, ROGUE_RISCVFW_REGION_REMAP_CR(BOOTLDR_CODE),
+ code_addr | common_opts | ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG0_FETCH_EN_EN);
+
+ pvr_cr_write64(pvr_dev, ROGUE_RISCVFW_REGION_REMAP_CR(BOOTLDR_DATA),
+ data_addr | common_opts |
+ ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG0_LOAD_STORE_EN_EN);
+
+ /* Garten IDLE bit controlled by RISC-V. */
+ pvr_cr_write64(pvr_dev, ROGUE_CR_MTS_GARTEN_WRAPPER_CONFIG,
+ ROGUE_CR_MTS_GARTEN_WRAPPER_CONFIG_IDLE_CTRL_META);
+
+ return 0;
+}
+
+struct rogue_riscv_fw_boot_data {
+ u64 coremem_code_dev_vaddr;
+ u64 coremem_data_dev_vaddr;
+ u32 coremem_code_fw_addr;
+ u32 coremem_data_fw_addr;
+ u32 coremem_code_size;
+ u32 coremem_data_size;
+ u32 flags;
+ u32 reserved;
+};
+
+static int
+pvr_riscv_fw_process(struct pvr_device *pvr_dev, const u8 *fw,
+ u8 *fw_code_ptr, u8 *fw_data_ptr, u8 *fw_core_code_ptr, u8 *fw_core_data_ptr,
+ u32 core_code_alloc_size)
+{
+ struct pvr_fw_device *fw_dev = &pvr_dev->fw_dev;
+ struct pvr_fw_mem *fw_mem = &fw_dev->mem;
+ struct rogue_riscv_fw_boot_data *boot_data;
+ int err;
+
+ err = pvr_fw_process_elf_command_stream(pvr_dev, fw, fw_code_ptr, fw_data_ptr,
+ fw_core_code_ptr, fw_core_data_ptr);
+ if (err)
+ goto err_out;
+
+ boot_data = (struct rogue_riscv_fw_boot_data *)fw_data_ptr;
+
+ if (fw_mem->core_code_obj) {
+ boot_data->coremem_code_dev_vaddr = pvr_fw_obj_get_gpu_addr(fw_mem->core_code_obj);
+ pvr_fw_object_get_fw_addr(fw_mem->core_code_obj, &boot_data->coremem_code_fw_addr);
+ boot_data->coremem_code_size = pvr_fw_obj_get_object_size(fw_mem->core_code_obj);
+ }
+
+ if (fw_mem->core_data_obj) {
+ boot_data->coremem_data_dev_vaddr = pvr_fw_obj_get_gpu_addr(fw_mem->core_data_obj);
+ pvr_fw_object_get_fw_addr(fw_mem->core_data_obj, &boot_data->coremem_data_fw_addr);
+ boot_data->coremem_data_size = pvr_fw_obj_get_object_size(fw_mem->core_data_obj);
+ }
+
+ return 0;
+
+err_out:
+ return err;
+}
+
+static int
+pvr_riscv_init(struct pvr_device *pvr_dev)
+{
+ pvr_fw_heap_info_init(pvr_dev, ROGUE_FW_HEAP_RISCV_SHIFT, 0);
+
+ return 0;
+}
+
+static u32
+pvr_riscv_get_fw_addr_with_offset(struct pvr_fw_object *fw_obj, u32 offset)
+{
+ u32 fw_addr = fw_obj->fw_addr_offset + offset;
+
+ /* RISC-V cacheability is determined by address. */
+ if (fw_obj->gem->flags & PVR_BO_FW_FLAGS_DEVICE_UNCACHED)
+ fw_addr |= ROGUE_RISCVFW_REGION_BASE(SHARED_UNCACHED_DATA);
+ else
+ fw_addr |= ROGUE_RISCVFW_REGION_BASE(SHARED_CACHED_DATA);
+
+ return fw_addr;
+}
+
+static int
+pvr_riscv_vm_map(struct pvr_device *pvr_dev, struct pvr_fw_object *fw_obj)
+{
+ struct pvr_gem_object *pvr_obj = fw_obj->gem;
+
+ return pvr_vm_map(pvr_dev->kernel_vm_ctx, pvr_obj, 0, fw_obj->fw_mm_node.start,
+ pvr_gem_object_size(pvr_obj));
+}
+
+static void
+pvr_riscv_vm_unmap(struct pvr_device *pvr_dev, struct pvr_fw_object *fw_obj)
+{
+ struct pvr_gem_object *pvr_obj = fw_obj->gem;
+
+ pvr_vm_unmap_obj(pvr_dev->kernel_vm_ctx, pvr_obj,
+ fw_obj->fw_mm_node.start, fw_obj->fw_mm_node.size);
+}
+
+static bool
+pvr_riscv_irq_pending(struct pvr_device *pvr_dev)
+{
+ return pvr_cr_read32(pvr_dev, ROGUE_CR_IRQ_OS0_EVENT_STATUS) &
+ ROGUE_CR_IRQ_OS0_EVENT_STATUS_SOURCE_EN;
+}
+
+static void
+pvr_riscv_irq_clear(struct pvr_device *pvr_dev)
+{
+ pvr_cr_write32(pvr_dev, ROGUE_CR_IRQ_OS0_EVENT_CLEAR,
+ ROGUE_CR_IRQ_OS0_EVENT_CLEAR_SOURCE_EN);
+}
+
+const struct pvr_fw_defs pvr_fw_defs_riscv = {
+ .init = pvr_riscv_init,
+ .fw_process = pvr_riscv_fw_process,
+ .vm_map = pvr_riscv_vm_map,
+ .vm_unmap = pvr_riscv_vm_unmap,
+ .get_fw_addr_with_offset = pvr_riscv_get_fw_addr_with_offset,
+ .wrapper_init = pvr_riscv_wrapper_init,
+ .irq_pending = pvr_riscv_irq_pending,
+ .irq_clear = pvr_riscv_irq_clear,
+ .has_fixed_data_addr = false,
+};
diff --git a/drivers/gpu/drm/imagination/pvr_fw_startstop.c b/drivers/gpu/drm/imagination/pvr_fw_startstop.c
index 36cec227cfe3cf5b1e293f48b164bb1be1b0ea54..dcbb9903e791e600db22d334b2e9580057edc89b 100644
--- a/drivers/gpu/drm/imagination/pvr_fw_startstop.c
+++ b/drivers/gpu/drm/imagination/pvr_fw_startstop.c
@@ -49,6 +49,14 @@ rogue_bif_init(struct pvr_device *pvr_dev)
pvr_cr_write64(pvr_dev, BIF_CAT_BASEX(MMU_CONTEXT_MAPPING_FWPRIV),
pc_addr);
+
+ if (pvr_dev->fw_dev.processor_type == PVR_FW_PROCESSOR_TYPE_RISCV) {
+ pc_addr = (((u64)pc_dma_addr >> ROGUE_CR_FWCORE_MEM_CAT_BASE0_ADDR_ALIGNSHIFT)
+ << ROGUE_CR_FWCORE_MEM_CAT_BASE0_ADDR_SHIFT) &
+ ~ROGUE_CR_FWCORE_MEM_CAT_BASE0_ADDR_CLRMSK;
+
+ pvr_cr_write64(pvr_dev, FWCORE_MEM_CAT_BASEX(MMU_CONTEXT_MAPPING_FWPRIV), pc_addr);
+ }
}
static int
@@ -114,6 +122,9 @@ pvr_fw_start(struct pvr_device *pvr_dev)
(void)pvr_cr_read32(pvr_dev, ROGUE_CR_SYS_BUS_SECURE); /* Fence write */
}
+ if (pvr_dev->fw_dev.processor_type == PVR_FW_PROCESSOR_TYPE_RISCV)
+ pvr_cr_write32(pvr_dev, ROGUE_CR_FWCORE_BOOT, 0);
+
/* Set Rogue in soft-reset. */
pvr_cr_write64(pvr_dev, ROGUE_CR_SOFT_RESET, soft_reset_mask);
if (has_reset2)
@@ -167,6 +178,12 @@ pvr_fw_start(struct pvr_device *pvr_dev)
/* ... and afterwards. */
udelay(3);
+ if (pvr_dev->fw_dev.processor_type == PVR_FW_PROCESSOR_TYPE_RISCV) {
+ /* Boot the FW. */
+ pvr_cr_write32(pvr_dev, ROGUE_CR_FWCORE_BOOT, 1);
+ udelay(3);
+ }
+
return 0;
err_reset:
diff --git a/drivers/gpu/drm/imagination/pvr_rogue_riscv.h b/drivers/gpu/drm/imagination/pvr_rogue_riscv.h
new file mode 100644
index 0000000000000000000000000000000000000000..9a070e24fa6a8bb44ff1e421ae6750cbf724d346
--- /dev/null
+++ b/drivers/gpu/drm/imagination/pvr_rogue_riscv.h
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
+/* Copyright (c) 2024 Imagination Technologies Ltd. */
+
+#ifndef PVR_ROGUE_RISCV_H
+#define PVR_ROGUE_RISCV_H
+
+#include "pvr_rogue_cr_defs.h"
+
+#include <linux/bitops.h>
+#include <linux/sizes.h>
+#include <linux/types.h>
+
+#define ROGUE_RISCVFW_REGION_SIZE SZ_256M
+#define ROGUE_RISCVFW_REGION_SHIFT __ffs(ROGUE_RISCVFW_REGION_SIZE)
+
+enum rogue_riscvfw_region {
+ ROGUE_RISCV_REGION__RESERVED_0 = 0,
+ ROGUE_RISCV_REGION__RESERVED_1,
+ ROGUE_RISCV_REGION_SOCIF,
+ ROGUE_RISCV_REGION__RESERVED_3,
+ ROGUE_RISCV_REGION__RESERVED_4,
+ ROGUE_RISCV_REGION_BOOTLDR_DATA,
+ ROGUE_RISCV_REGION_SHARED_CACHED_DATA,
+ ROGUE_RISCV_REGION__RESERVED_7,
+ ROGUE_RISCV_REGION_COREMEM,
+ ROGUE_RISCV_REGION__RESERVED_9,
+ ROGUE_RISCV_REGION__RESERVED_A,
+ ROGUE_RISCV_REGION__RESERVED_B,
+ ROGUE_RISCV_REGION_BOOTLDR_CODE,
+ ROGUE_RISCV_REGION_SHARED_UNCACHED_DATA,
+ ROGUE_RISCV_REGION__RESERVED_E,
+ ROGUE_RISCV_REGION__RESERVED_F,
+
+ ROGUE_RISCV_REGION__COUNT,
+};
+
+#define ROGUE_RISCVFW_REGION_BASE(r) ((u32)(ROGUE_RISCV_REGION_##r) << ROGUE_RISCVFW_REGION_SHIFT)
+#define ROGUE_RISCVFW_REGION_REMAP_CR(r) \
+ (ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG0 + (u32)(ROGUE_RISCV_REGION_##r) * 8U)
+
+#endif /* PVR_ROGUE_RISCV_H */
--
2.49.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v4 15/18] drm/imagination: Use cached memory with dma_coherent
2025-03-20 11:32 [PATCH v4 00/18] Imagination BXS-4-64 MC1 GPU support Matt Coster
` (13 preceding siblings ...)
2025-03-20 11:32 ` [PATCH v4 14/18] drm/imagination: Add RISC-V firmware processor support Matt Coster
@ 2025-03-20 11:32 ` Matt Coster
2025-03-20 11:32 ` [PATCH v4 16/18] drm/imagination: Add support for TI AM68 GPU Matt Coster
` (2 subsequent siblings)
17 siblings, 0 replies; 21+ messages in thread
From: Matt Coster @ 2025-03-20 11:32 UTC (permalink / raw)
To: Frank Binns, Matt Coster, David Airlie, Simona Vetter,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Nishanth Menon,
Vignesh Raghavendra, Tero Kristo
Cc: dri-devel, devicetree, linux-kernel, linux-arm-kernel,
Randolph Sapp, Darren Etheridge, Michal Wilczynski, Alessio Belle,
Alexandru Dadu
The TI k3-j721s2 platform does not allow us to use uncached memory
(which is what the driver currently does) without disabling cache snooping
on the AXI ACE-Lite interface, which would be too much of a performance
hit.
Given the platform is dma-coherent, we can simply force all
device-accessible memory allocations through the CPU cache. In fact, this
can be done whenever the dma_coherent attribute is present.
Signed-off-by: Matt Coster <matt.coster@imgtec.com>
---
Changes in v4:
- None
- Link to v3: https://lore.kernel.org/r/20250310-sets-bxs-4-64-patch-v1-v3-15-143b3dbef02f@imgtec.com
Changes in v3:
- Change from a workaround to a regular codepath
- Add missing <linux/property.h> include
- Link to v2: https://lore.kernel.org/r/20241118-sets-bxs-4-64-patch-v1-v2-19-3fd45d9fb0cf@imgtec.com
Changes in v2:
- None
- Link to v1: https://lore.kernel.org/r/20241105-sets-bxs-4-64-patch-v1-v1-19-4ed30e865892@imgtec.com
---
drivers/gpu/drm/imagination/pvr_gem.c | 10 +++++++---
drivers/gpu/drm/imagination/pvr_gem.h | 6 ++++--
drivers/gpu/drm/imagination/pvr_mmu.c | 8 +++++++-
3 files changed, 18 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/imagination/pvr_gem.c b/drivers/gpu/drm/imagination/pvr_gem.c
index 6a8c81fe8c1e85c2130a4fe90fce35b6a2be35aa..9467cd563339cd5bf62ff92edba115ed5721ee76 100644
--- a/drivers/gpu/drm/imagination/pvr_gem.c
+++ b/drivers/gpu/drm/imagination/pvr_gem.c
@@ -19,6 +19,7 @@
#include <linux/log2.h>
#include <linux/mutex.h>
#include <linux/pagemap.h>
+#include <linux/property.h>
#include <linux/refcount.h>
#include <linux/scatterlist.h>
@@ -336,6 +337,7 @@ struct drm_gem_object *pvr_gem_create_object(struct drm_device *drm_dev, size_t
struct pvr_gem_object *
pvr_gem_object_create(struct pvr_device *pvr_dev, size_t size, u64 flags)
{
+ struct drm_device *drm_dev = from_pvr_device(pvr_dev);
struct drm_gem_shmem_object *shmem_obj;
struct pvr_gem_object *pvr_obj;
struct sg_table *sgt;
@@ -345,7 +347,10 @@ pvr_gem_object_create(struct pvr_device *pvr_dev, size_t size, u64 flags)
if (size == 0 || !pvr_gem_object_flags_validate(flags))
return ERR_PTR(-EINVAL);
- shmem_obj = drm_gem_shmem_create(from_pvr_device(pvr_dev), size);
+ if (device_get_dma_attr(drm_dev->dev) == DEV_DMA_COHERENT)
+ flags |= PVR_BO_CPU_CACHED;
+
+ shmem_obj = drm_gem_shmem_create(drm_dev, size);
if (IS_ERR(shmem_obj))
return ERR_CAST(shmem_obj);
@@ -360,8 +365,7 @@ pvr_gem_object_create(struct pvr_device *pvr_dev, size_t size, u64 flags)
goto err_shmem_object_free;
}
- dma_sync_sgtable_for_device(shmem_obj->base.dev->dev, sgt,
- DMA_BIDIRECTIONAL);
+ dma_sync_sgtable_for_device(drm_dev->dev, sgt, DMA_BIDIRECTIONAL);
/*
* Do this last because pvr_gem_object_zero() requires a fully
diff --git a/drivers/gpu/drm/imagination/pvr_gem.h b/drivers/gpu/drm/imagination/pvr_gem.h
index e0e5ea509a2e88a437b8d241ea13c7bab2220f56..c99f30cc62088c030bd8a806df79b738b62a968f 100644
--- a/drivers/gpu/drm/imagination/pvr_gem.h
+++ b/drivers/gpu/drm/imagination/pvr_gem.h
@@ -44,8 +44,10 @@ struct pvr_file;
* Bits not defined anywhere are "undefined".
*
* CPU mapping options
- * :PVR_BO_CPU_CACHED: By default, all GEM objects are mapped write-combined on the CPU. Set this
- * flag to override this behaviour and map the object cached.
+ * :PVR_BO_CPU_CACHED: By default, all GEM objects are mapped write-combined on the CPU. Set
+ * this flag to override this behaviour and map the object cached. If the dma_coherent
+ * property is present in devicetree, all allocations will be mapped as if this flag was set.
+ * This does not require any additional consideration at allocation time.
*
* Firmware options
* :PVR_BO_FW_NO_CLEAR_ON_RESET: By default, all FW objects are cleared and reinitialised on hard
diff --git a/drivers/gpu/drm/imagination/pvr_mmu.c b/drivers/gpu/drm/imagination/pvr_mmu.c
index 4fe70610ed94cf707e631f8148af081a94f97327..450d476d183f0173d0ef03f0d8897fbeb04831a2 100644
--- a/drivers/gpu/drm/imagination/pvr_mmu.c
+++ b/drivers/gpu/drm/imagination/pvr_mmu.c
@@ -17,6 +17,7 @@
#include <linux/dma-mapping.h>
#include <linux/kmemleak.h>
#include <linux/minmax.h>
+#include <linux/property.h>
#include <linux/sizes.h>
#define PVR_SHIFT_FROM_SIZE(size_) (__builtin_ctzll(size_))
@@ -259,6 +260,7 @@ pvr_mmu_backing_page_init(struct pvr_mmu_backing_page *page,
struct device *dev = from_pvr_device(pvr_dev)->dev;
struct page *raw_page;
+ pgprot_t prot;
int err;
dma_addr_t dma_addr;
@@ -268,7 +270,11 @@ pvr_mmu_backing_page_init(struct pvr_mmu_backing_page *page,
if (!raw_page)
return -ENOMEM;
- host_ptr = vmap(&raw_page, 1, VM_MAP, pgprot_writecombine(PAGE_KERNEL));
+ prot = PAGE_KERNEL;
+ if (device_get_dma_attr(dev) != DEV_DMA_COHERENT)
+ prot = pgprot_writecombine(prot);
+
+ host_ptr = vmap(&raw_page, 1, VM_MAP, prot);
if (!host_ptr) {
err = -ENOMEM;
goto err_free_page;
--
2.49.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v4 16/18] drm/imagination: Add support for TI AM68 GPU
2025-03-20 11:32 [PATCH v4 00/18] Imagination BXS-4-64 MC1 GPU support Matt Coster
` (14 preceding siblings ...)
2025-03-20 11:32 ` [PATCH v4 15/18] drm/imagination: Use cached memory with dma_coherent Matt Coster
@ 2025-03-20 11:32 ` Matt Coster
2025-03-20 11:32 ` [PATCH DO NOT MERGE v4 17/18] arm64: dts: ti: k3-am62: New GPU binding details Matt Coster
2025-03-20 11:32 ` [PATCH DO NOT MERGE v4 18/18] arm64: dts: ti: k3-j721s2: Add GPU node Matt Coster
17 siblings, 0 replies; 21+ messages in thread
From: Matt Coster @ 2025-03-20 11:32 UTC (permalink / raw)
To: Frank Binns, Matt Coster, David Airlie, Simona Vetter,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Nishanth Menon,
Vignesh Raghavendra, Tero Kristo
Cc: dri-devel, devicetree, linux-kernel, linux-arm-kernel,
Randolph Sapp, Darren Etheridge, Michal Wilczynski, Alessio Belle,
Alexandru Dadu
Since we already added a generic compatible string for all IMG Rogue GPUs
("img,img-rogue"), all that's needed here is to link the appropriate
firmware for the BXS-4-64 GPU in the AM68.
Signed-off-by: Matt Coster <matt.coster@imgtec.com>
---
Changes in v4:
- None
- Link to v3: https://lore.kernel.org/r/20250310-sets-bxs-4-64-patch-v1-v3-16-143b3dbef02f@imgtec.com
Changes in v3:
- Remove device overrides
- Remove specific compatible string
- Link to v2: https://lore.kernel.org/r/20241118-sets-bxs-4-64-patch-v1-v2-20-3fd45d9fb0cf@imgtec.com
Changes in v2:
- None
- Link to v1: https://lore.kernel.org/r/20241105-sets-bxs-4-64-patch-v1-v1-20-4ed30e865892@imgtec.com
---
drivers/gpu/drm/imagination/pvr_drv.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/imagination/pvr_drv.c b/drivers/gpu/drm/imagination/pvr_drv.c
index ac4f5855c5692f0956862cebdbf76b16d8da9a81..b058ec183bb30ab5c3db17ebaadf2754520a2a1f 100644
--- a/drivers/gpu/drm/imagination/pvr_drv.c
+++ b/drivers/gpu/drm/imagination/pvr_drv.c
@@ -44,6 +44,7 @@
* This driver supports the following PowerVR/IMG graphics cores from Imagination Technologies:
*
* * AXE-1-16M (found in Texas Instruments AM62)
+ * * BXS-4-64 MC1 (found in Texas Instruments J721S2/AM68)
*/
/**
@@ -1512,3 +1513,4 @@ MODULE_DESCRIPTION(PVR_DRIVER_DESC);
MODULE_LICENSE("Dual MIT/GPL");
MODULE_IMPORT_NS("DMA_BUF");
MODULE_FIRMWARE("powervr/rogue_33.15.11.3_v1.fw");
+MODULE_FIRMWARE("powervr/rogue_36.53.104.796_v1.fw");
--
2.49.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH DO NOT MERGE v4 17/18] arm64: dts: ti: k3-am62: New GPU binding details
2025-03-20 11:32 [PATCH v4 00/18] Imagination BXS-4-64 MC1 GPU support Matt Coster
` (15 preceding siblings ...)
2025-03-20 11:32 ` [PATCH v4 16/18] drm/imagination: Add support for TI AM68 GPU Matt Coster
@ 2025-03-20 11:32 ` Matt Coster
2025-03-20 11:32 ` [PATCH DO NOT MERGE v4 18/18] arm64: dts: ti: k3-j721s2: Add GPU node Matt Coster
17 siblings, 0 replies; 21+ messages in thread
From: Matt Coster @ 2025-03-20 11:32 UTC (permalink / raw)
To: Frank Binns, Matt Coster, David Airlie, Simona Vetter,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Nishanth Menon,
Vignesh Raghavendra, Tero Kristo
Cc: dri-devel, devicetree, linux-kernel, linux-arm-kernel,
Randolph Sapp, Darren Etheridge, Michal Wilczynski, Alessio Belle,
Alexandru Dadu
Use the new compatible string introduced earlier (in "dt-bindings: gpu:
img: More explicit compatible strings") and add a name to the single power
domain for this GPU (introduced in "dt-bindings: gpu: img: Power domain
details").
Signed-off-by: Matt Coster <matt.coster@imgtec.com>
---
Changes in v4:
- None
- Link to v3: https://lore.kernel.org/r/20250310-sets-bxs-4-64-patch-v1-v3-17-143b3dbef02f@imgtec.com
Changes in v3:
- None
- Link to v2: https://lore.kernel.org/r/20241118-sets-bxs-4-64-patch-v1-v2-7-3fd45d9fb0cf@imgtec.com
Changes in v2:
- None
- Link to v1: https://lore.kernel.org/r/20241105-sets-bxs-4-64-patch-v1-v1-7-4ed30e865892@imgtec.com
---
arch/arm64/boot/dts/ti/k3-am62-main.dtsi | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
index 7d355aa73ea2116723735f70b9351cefcd8bc118..d17b25cae196b08d24adbe7c913ccaba7eed37eb 100644
--- a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
@@ -691,12 +691,14 @@ ospi0: spi@fc40000 {
};
gpu: gpu@fd00000 {
- compatible = "ti,am62-gpu", "img,img-axe";
+ compatible = "ti,am62-gpu", "img,img-axe-1-16m", "img,img-axe",
+ "img,img-rogue";
reg = <0x00 0x0fd00000 0x00 0x20000>;
clocks = <&k3_clks 187 0>;
clock-names = "core";
interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
power-domains = <&k3_pds 187 TI_SCI_PD_EXCLUSIVE>;
+ power-domain-names = "a";
};
cpsw3g: ethernet@8000000 {
--
2.49.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH DO NOT MERGE v4 18/18] arm64: dts: ti: k3-j721s2: Add GPU node
2025-03-20 11:32 [PATCH v4 00/18] Imagination BXS-4-64 MC1 GPU support Matt Coster
` (16 preceding siblings ...)
2025-03-20 11:32 ` [PATCH DO NOT MERGE v4 17/18] arm64: dts: ti: k3-am62: New GPU binding details Matt Coster
@ 2025-03-20 11:32 ` Matt Coster
17 siblings, 0 replies; 21+ messages in thread
From: Matt Coster @ 2025-03-20 11:32 UTC (permalink / raw)
To: Frank Binns, Matt Coster, David Airlie, Simona Vetter,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Nishanth Menon,
Vignesh Raghavendra, Tero Kristo
Cc: dri-devel, devicetree, linux-kernel, linux-arm-kernel,
Randolph Sapp, Darren Etheridge, Michal Wilczynski, Alessio Belle,
Alexandru Dadu
The J721S2 binding is based on the TI downstream binding in 54b0f2a00d92
("arm64: dts: ti: k3-j721s2-main: add gpu node") from [1] but with updated
compatible strings.
The clock[2] and power[3] indices were verified from docs, but the
source of the interrupt index remains elusive.
[1]: https://git.ti.com/cgit/ti-linux-kernel/ti-linux-kernel
[2]: https://downloads.ti.com/tisci/esd/latest/5_soc_doc/j721s2/clocks.html
[3]: https://downloads.ti.com/tisci/esd/latest/5_soc_doc/j721s2/devices.html
Signed-off-by: Matt Coster <matt.coster@imgtec.com>
---
Changes in v4:
- None
- Link to v3: https://lore.kernel.org/r/20250310-sets-bxs-4-64-patch-v1-v3-18-143b3dbef02f@imgtec.com
Changes in v3:
- None
- Link to v2: https://lore.kernel.org/r/20241118-sets-bxs-4-64-patch-v1-v2-21-3fd45d9fb0cf@imgtec.com
Changes in v2:
- Use normal reg syntax for 64-bit values
- Link to v1: https://lore.kernel.org/r/20241105-sets-bxs-4-64-patch-v1-v1-21-4ed30e865892@imgtec.com
---
arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi b/arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi
index 92bf48fdbeba45ecca8c854db5f72fd3666239c5..a79ac41b2c1f51b7193e6133864428bd35a5e835 100644
--- a/arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi
@@ -2048,4 +2048,16 @@ watchdog8: watchdog@23f0000 {
/* reserved for MAIN_R5F1_1 */
status = "reserved";
};
+
+ gpu: gpu@4e20000000 {
+ compatible = "ti,j721s2-gpu", "img,img-bxs-4-64", "img,img-rogue";
+ reg = <0x4e 0x20000000 0x00 0x80000>;
+ clocks = <&k3_clks 130 1>;
+ clock-names = "core";
+ interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
+ power-domains = <&k3_pds 130 TI_SCI_PD_EXCLUSIVE>,
+ <&k3_pds 373 TI_SCI_PD_EXCLUSIVE>;
+ power-domain-names = "a", "b";
+ dma-coherent;
+ };
};
--
2.49.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [PATCH v4 01/18] dt-bindings: gpu: img: Future-proofing enhancements
2025-03-20 11:32 ` [PATCH v4 01/18] dt-bindings: gpu: img: Future-proofing enhancements Matt Coster
@ 2025-03-20 20:32 ` Rob Herring (Arm)
0 siblings, 0 replies; 21+ messages in thread
From: Rob Herring (Arm) @ 2025-03-20 20:32 UTC (permalink / raw)
To: Matt Coster
Cc: Alexandru Dadu, Conor Dooley, Michal Wilczynski,
Thomas Zimmermann, Darren Etheridge, Alessio Belle, Simona Vetter,
Vignesh Raghavendra, Krzysztof Kozlowski, linux-arm-kernel,
Maxime Ripard, devicetree, dri-devel, linux-kernel,
Nishanth Menon, Maarten Lankhorst, Tero Kristo, David Airlie,
Randolph Sapp, Frank Binns
On Thu, 20 Mar 2025 11:32:11 +0000, Matt Coster wrote:
> The first compatible strings added for the AXE-1-16M are not sufficient to
> accurately describe all the IMG Rogue GPUs. The current "img,img-axe"
> string refers to the entire family of Series AXE GPUs, but this is
> primarily a marketing term and does not denote a level of hardware
> similarity any greater than just "Rogue".
>
> The more specific "img,img-axe-1-16m" string refers to individual AXE-1-16M
> GPU. For example, unlike the rest of the Series AXE GPUs, the AXE-1-16M
> only uses a single power domain.
>
> The situation is actually slightly worse than described in the first
> paragraph, since many "series" (such as Series BXS found in the TI AM68
> among others and added later in this series) contain cores with both Rogue
> and Volcanic architectures.
>
> Besides attempting to move away from vague groupings defined only
> by marketing terms, we want to draw a line between properties inherent to
> the IP core and choices made by the silicon vendor at integration time.
> For instance, the number of power domains is a property of the IP core,
> whereas the decision to use one or multiple clocks is a vendor one.
>
> In the original compatible strings, we must use "ti,am62-gpu" to constrain
> both of these properties since the number of power domains cannot be fixed
> for "img,img-axe".
>
> Work is currently underway to add support for volcanic-based Imagination
> GPUs, for which bindings will be added in "img,powervr-volcanic.yaml".
> As alluded to previously, the split between rogue and volcanic cores is
> non-obvious at times, so add a generic top-level "img,img-rogue" compatible
> string here to allow for simpler differentiation in devicetrees without
> referring back to the bindings.
>
> The currently supported GPU (AXE-1-16M) only requires a single power
> domain. Subsequent patches will add support for BXS-4-64 MC1, which has
> two power domains. Add infrastructure now to allow for this.
>
> Also allow the dma-coherent property to be added to IMG Rogue GPUs, which
> are DMA devices. The decision for coherency is made at integration time and
> this property should be applied wherever it accurately describes the
> vendor integration.
>
> Note that the new required properties for power domains are conditional on
> the new base compatible string to avoid an ABI break.
>
> Signed-off-by: Matt Coster <matt.coster@imgtec.com>
> ---
> Changes in v4:
> - Add img,img-rogue back to ti,am62-gpu compatible strings to allow
> compatibility with older kernels
> - Revert change to power-domains property and add proper constraint
> - Link to v3: https://lore.kernel.org/r/20250310-sets-bxs-4-64-patch-v1-v3-1-143b3dbef02f@imgtec.com
> Changes in v3:
> - Remove unnecessary example
> - Remove second power domain details, add these where they're used instead
> - Avoid ABI breaks by limiting new required properties to new compatible
> strings and making all binding changes in a single patch.
> - Links to v2:
> https://lore.kernel.org/r/20241118-sets-bxs-4-64-patch-v1-v2-1-3fd45d9fb0cf@imgtec.com
> https://lore.kernel.org/r/20241118-sets-bxs-4-64-patch-v1-v2-3-3fd45d9fb0cf@imgtec.com
> https://lore.kernel.org/r/20241118-sets-bxs-4-64-patch-v1-v2-4-3fd45d9fb0cf@imgtec.com
> ---
> .../devicetree/bindings/gpu/img,powervr-rogue.yaml | 44 +++++++++++++++++++---
> 1 file changed, 39 insertions(+), 5 deletions(-)
>
My bot found errors running 'make dt_binding_check' on your patch:
yamllint warnings/errors:
dtschema/dtc warnings/errors:
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/gpu/img,powervr-rogue.yaml: properties:power-domains: 'anyOf' conditional failed, one must be fixed:
'minItems' is not one of ['maxItems', 'description', 'deprecated']
hint: Only "maxItems" is required for a single entry if there are no constraints defined for the values.
'minItems' is not one of ['description', 'deprecated', 'const', 'enum', 'minimum', 'maximum', 'multipleOf', 'default', '$ref', 'oneOf']
'maxItems' is not one of ['description', 'deprecated', 'const', 'enum', 'minimum', 'maximum', 'multipleOf', 'default', '$ref', 'oneOf']
1 is less than the minimum of 2
hint: Arrays must be described with a combination of minItems/maxItems/items
hint: cell array properties must define how many entries and what the entries are when there is more than one entry.
from schema $id: http://devicetree.org/meta-schemas/power-domain.yaml#
doc reference errors (make refcheckdocs):
See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20250320-sets-bxs-4-64-patch-v1-v4-1-d987cf4ca439@imgtec.com
The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.
If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:
pip3 install dtschema --upgrade
Please check and re-submit after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v4 02/18] dt-bindings: gpu: img: Add BXS-4-64 devicetree bindings
2025-03-20 11:32 ` [PATCH v4 02/18] dt-bindings: gpu: img: Add BXS-4-64 devicetree bindings Matt Coster
@ 2025-03-21 8:10 ` Krzysztof Kozlowski
0 siblings, 0 replies; 21+ messages in thread
From: Krzysztof Kozlowski @ 2025-03-21 8:10 UTC (permalink / raw)
To: Matt Coster
Cc: Frank Binns, David Airlie, Simona Vetter, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Nishanth Menon,
Vignesh Raghavendra, Tero Kristo, dri-devel, devicetree,
linux-kernel, linux-arm-kernel, Randolph Sapp, Darren Etheridge,
Michal Wilczynski, Alessio Belle, Alexandru Dadu
On Thu, Mar 20, 2025 at 11:32:12AM +0000, Matt Coster wrote:
> + - if:
> + properties:
> + compatible:
> + contains:
> + const: img,img-bxs-4-64
> + then:
> + properties:
> + power-domains:
> + minItems: 2
> + power-domain-names:
> + minItems: 2
> +
> + - if:
> + properties:
> + compatible:
> + contains:
> + anyOf:
Instead: enum
> + - const: ti,am62-gpu
> + - const: ti,j721s2-gpu
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 21+ messages in thread
end of thread, other threads:[~2025-03-21 8:14 UTC | newest]
Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-03-20 11:32 [PATCH v4 00/18] Imagination BXS-4-64 MC1 GPU support Matt Coster
2025-03-20 11:32 ` [PATCH v4 01/18] dt-bindings: gpu: img: Future-proofing enhancements Matt Coster
2025-03-20 20:32 ` Rob Herring (Arm)
2025-03-20 11:32 ` [PATCH v4 02/18] dt-bindings: gpu: img: Add BXS-4-64 devicetree bindings Matt Coster
2025-03-21 8:10 ` Krzysztof Kozlowski
2025-03-20 11:32 ` [PATCH v4 03/18] drm/imagination: Update register defs for newer GPUs Matt Coster
2025-03-20 11:32 ` [PATCH v4 04/18] drm/imagination: Use new generic compatible string Matt Coster
2025-03-20 11:32 ` [PATCH v4 05/18] drm/imagination: Add power domain control Matt Coster
2025-03-20 11:32 ` [PATCH v4 06/18] drm/imagination: Mask GPU IRQs in threaded handler Matt Coster
2025-03-20 11:32 ` [PATCH v4 07/18] drm/imagination: Handle Rogue safety event IRQs Matt Coster
2025-03-20 11:32 ` [PATCH v4 08/18] drm/imagination: Remove firmware enable_reg Matt Coster
2025-03-20 11:32 ` [PATCH v4 09/18] drm/imagination: Rename event_mask -> status_mask Matt Coster
2025-03-20 11:32 ` [PATCH v4 10/18] drm/imagination: Make has_fixed_data_addr a value Matt Coster
2025-03-20 11:32 ` [PATCH v4 11/18] drm/imagination: Use a lookup table for fw defs Matt Coster
2025-03-20 11:32 ` [PATCH v4 12/18] drm/imagination: Use callbacks for fw irq handling Matt Coster
2025-03-20 11:32 ` [PATCH v4 13/18] drm/imagination: Move ELF fw utils to common file Matt Coster
2025-03-20 11:32 ` [PATCH v4 14/18] drm/imagination: Add RISC-V firmware processor support Matt Coster
2025-03-20 11:32 ` [PATCH v4 15/18] drm/imagination: Use cached memory with dma_coherent Matt Coster
2025-03-20 11:32 ` [PATCH v4 16/18] drm/imagination: Add support for TI AM68 GPU Matt Coster
2025-03-20 11:32 ` [PATCH DO NOT MERGE v4 17/18] arm64: dts: ti: k3-am62: New GPU binding details Matt Coster
2025-03-20 11:32 ` [PATCH DO NOT MERGE v4 18/18] arm64: dts: ti: k3-j721s2: Add GPU node Matt Coster
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).