summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/arm/arm,coresight-cti.yaml3
-rw-r--r--Documentation/devicetree/bindings/arm/arm,coresight-dynamic-funnel.yaml3
-rw-r--r--Documentation/devicetree/bindings/arm/arm,coresight-etm.yaml3
-rw-r--r--Documentation/devicetree/bindings/arm/arm,coresight-stm.yaml3
-rw-r--r--Documentation/devicetree/bindings/arm/arm,coresight-tmc.yaml3
-rw-r--r--Documentation/devicetree/bindings/arm/arm,coresight-tpiu.yaml3
-rw-r--r--Documentation/devicetree/bindings/arm/atmel,at91rm9200-sdramc.yaml66
-rw-r--r--Documentation/devicetree/bindings/arm/atmel,at91rm9200-st.yaml69
-rw-r--r--Documentation/devicetree/bindings/arm/atmel,at91sam9260-pit.yaml49
-rw-r--r--Documentation/devicetree/bindings/arm/atmel-sysregs.txt48
-rw-r--r--Documentation/devicetree/bindings/arm/freescale/fsl,imx7ulp-pm.yaml5
-rw-r--r--Documentation/devicetree/bindings/arm/fsl.yaml86
-rw-r--r--Documentation/devicetree/bindings/arm/microchip,sam9x60-pit64b.yaml68
-rw-r--r--Documentation/devicetree/bindings/arm/microchip,sama7g5-chipid.yaml41
-rw-r--r--Documentation/devicetree/bindings/arm/nxp/lpc32xx.yaml22
-rw-r--r--Documentation/devicetree/bindings/arm/tegra.yaml56
-rw-r--r--Documentation/devicetree/bindings/arm/tegra/nvidia,tegra234-cbb.yaml4
-rw-r--r--Documentation/devicetree/bindings/bus/st,stm32mp131-dbg-bus.yaml76
-rw-r--r--Documentation/devicetree/bindings/cache/baikal,bt1-l2-ctl.yaml63
-rw-r--r--Documentation/devicetree/bindings/cache/qcom,llcc.yaml2
-rw-r--r--Documentation/devicetree/bindings/clock/nvidia,tegra124-dfll.txt155
-rw-r--r--Documentation/devicetree/bindings/clock/nvidia,tegra124-dfll.yaml290
-rw-r--r--Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-hdmi.yaml13
-rw-r--r--Documentation/devicetree/bindings/firmware/arm,scmi.yaml10
-rw-r--r--Documentation/devicetree/bindings/firmware/google,gs101-acpm-ipc.yaml50
-rw-r--r--Documentation/devicetree/bindings/firmware/qcom,scm.yaml4
-rw-r--r--Documentation/devicetree/bindings/interrupt-controller/fsl,irqsteer.yaml4
-rw-r--r--Documentation/devicetree/bindings/interrupt-controller/nvidia,tegra20-ictlr.yaml23
-rw-r--r--Documentation/devicetree/bindings/memory-controllers/nvidia,tegra210-emc.yaml6
-rw-r--r--Documentation/devicetree/bindings/memory-controllers/nvidia,tegra210-mc.yaml77
-rw-r--r--Documentation/devicetree/bindings/phy/nvidia,tegra194-xusb-padctl.yaml39
-rw-r--r--Documentation/devicetree/bindings/phy/nvidia,tegra20-usb-phy.yaml1
-rw-r--r--Documentation/devicetree/bindings/pinctrl/st,stm32-hdp.yaml6
-rw-r--r--Documentation/devicetree/bindings/reset/renesas,rzv2h-usb2phy-reset.yaml9
-rw-r--r--Documentation/devicetree/bindings/soc/cix/cix,sky1-system-control.yaml42
-rw-r--r--Documentation/devicetree/bindings/soc/imx/fsl,imx93-media-blk-ctrl.yaml78
-rw-r--r--Documentation/devicetree/bindings/soc/microchip/microchip,mpfs-irqmux.yaml103
-rw-r--r--Documentation/devicetree/bindings/soc/microchip/microchip,mpfs-mss-top-sysreg.yaml18
-rw-r--r--Documentation/devicetree/bindings/soc/microchip/microchip,mpfs-sys-controller.yaml4
-rw-r--r--Documentation/devicetree/bindings/soc/qcom/qcom,pmic-glink.yaml2
-rw-r--r--Documentation/devicetree/bindings/soc/renesas/renesas,rzg2l-sysc.yaml1
-rw-r--r--Documentation/devicetree/bindings/soc/renesas/renesas.yaml13
-rw-r--r--Documentation/driver-api/reset.rst1
-rw-r--r--MAINTAINERS20
-rw-r--r--drivers/bus/Kconfig10
-rw-r--r--drivers/bus/Makefile1
-rw-r--r--drivers/bus/imx-aipstz.c15
-rw-r--r--drivers/bus/stm32_dbg_bus.c250
-rw-r--r--drivers/bus/stm32_etzpc.c3
-rw-r--r--drivers/bus/stm32_firewall.c59
-rw-r--r--drivers/bus/stm32_rifsc.c61
-rw-r--r--drivers/clk/samsung/clk-acpm.c4
-rw-r--r--drivers/clk/spear/clk-vco-pll.c4
-rw-r--r--drivers/firmware/arm_ffa/driver.c2
-rw-r--r--drivers/firmware/arm_scmi/base.c4
-rw-r--r--drivers/firmware/arm_scmi/common.h4
-rw-r--r--drivers/firmware/arm_scmi/driver.c4
-rw-r--r--drivers/firmware/arm_scmi/quirks.h8
-rw-r--r--drivers/firmware/qcom/qcom_qseecom_uefisecapp.c9
-rw-r--r--drivers/firmware/qcom/qcom_scm.c71
-rw-r--r--drivers/firmware/samsung/exynos-acpm-dvfs.c13
-rw-r--r--drivers/firmware/samsung/exynos-acpm-dvfs.h4
-rw-r--r--drivers/firmware/samsung/exynos-acpm-pmic.c26
-rw-r--r--drivers/firmware/samsung/exynos-acpm-pmic.h10
-rw-r--r--drivers/firmware/samsung/exynos-acpm.c30
-rw-r--r--drivers/firmware/samsung/exynos-acpm.h10
-rw-r--r--drivers/firmware/tegra/bpmp.c34
-rw-r--r--drivers/gpio/Kconfig1
-rw-r--r--drivers/gpio/gpio-mpfs.c122
-rw-r--r--drivers/memory/Kconfig11
-rw-r--r--drivers/memory/Makefile1
-rw-r--r--drivers/memory/brcmstb_memc.c8
-rw-r--r--drivers/memory/bt1-l2-ctl.c323
-rw-r--r--drivers/memory/renesas-rpc-if.c8
-rw-r--r--drivers/memory/tegra/mc.c135
-rw-r--r--drivers/memory/tegra/mc.h153
-rw-r--r--drivers/memory/tegra/tegra114.c18
-rw-r--r--drivers/memory/tegra/tegra124-emc.c2
-rw-r--r--drivers/memory/tegra/tegra124.c40
-rw-r--r--drivers/memory/tegra/tegra186-emc.c8
-rw-r--r--drivers/memory/tegra/tegra186.c22
-rw-r--r--drivers/memory/tegra/tegra194.c22
-rw-r--r--drivers/memory/tegra/tegra20.c31
-rw-r--r--drivers/memory/tegra/tegra210.c21
-rw-r--r--drivers/memory/tegra/tegra234.c22
-rw-r--r--drivers/memory/tegra/tegra264.c420
-rw-r--r--drivers/memory/tegra/tegra30-emc.c6
-rw-r--r--drivers/memory/tegra/tegra30.c18
-rw-r--r--drivers/mfd/sec-acpm.c10
-rw-r--r--drivers/pinctrl/stm32/pinctrl-stm32-hdp.c14
-rw-r--r--drivers/reset/Kconfig9
-rw-r--r--drivers/reset/Makefile1
-rw-r--r--drivers/reset/core.c505
-rw-r--r--drivers/reset/reset-ath79.c12
-rw-r--r--drivers/reset/reset-gpio.c27
-rw-r--r--drivers/reset/reset-intel-gw.c11
-rw-r--r--drivers/reset/reset-lpc18xx.c12
-rw-r--r--drivers/reset/reset-ma35d1.c11
-rw-r--r--drivers/reset/reset-npcm.c12
-rw-r--r--drivers/reset/reset-rzv2h-usb2phy.c197
-rw-r--r--drivers/reset/reset-sky1.c367
-rw-r--r--drivers/reset/reset-sunplus.c12
-rw-r--r--drivers/reset/sti/reset-syscfg.c9
-rw-r--r--drivers/soc/hisilicon/kunpeng_hccs.c7
-rw-r--r--drivers/soc/microchip/Kconfig11
-rw-r--r--drivers/soc/microchip/Makefile1
-rw-r--r--drivers/soc/microchip/mpfs-irqmux.c181
-rw-r--r--drivers/soc/microchip/mpfs-sys-controller.c74
-rw-r--r--drivers/soc/qcom/llcc-qcom.c188
-rw-r--r--drivers/soc/qcom/ocmem.c17
-rw-r--r--drivers/soc/qcom/pdr_interface.c4
-rw-r--r--drivers/soc/qcom/pdr_internal.h3
-rw-r--r--drivers/soc/qcom/pmic_glink.c66
-rw-r--r--drivers/soc/qcom/qcom_aoss.c2
-rw-r--r--drivers/soc/qcom/qcom_pd_mapper.c33
-rw-r--r--drivers/soc/qcom/smp2p.c103
-rw-r--r--drivers/soc/qcom/socinfo.c11
-rw-r--r--drivers/soc/qcom/ubwc_config.c31
-rw-r--r--drivers/soc/qcom/wcnss_ctrl.c17
-rw-r--r--drivers/soc/renesas/Kconfig12
-rw-r--r--drivers/soc/renesas/Makefile1
-rw-r--r--drivers/soc/renesas/r9a08g046-sysc.c91
-rw-r--r--drivers/soc/renesas/r9a09g047-sys.c2
-rw-r--r--drivers/soc/renesas/r9a09g056-sys.c2
-rw-r--r--drivers/soc/renesas/r9a09g057-sys.c2
-rw-r--r--drivers/soc/renesas/rz-sysc.c3
-rw-r--r--drivers/soc/renesas/rz-sysc.h1
-rw-r--r--drivers/soc/tegra/Kconfig20
-rw-r--r--drivers/soc/tegra/cbb/tegra234-cbb.c169
-rw-r--r--drivers/soc/tegra/common.c5
-rw-r--r--drivers/soc/tegra/pmc.c664
-rw-r--r--drivers/tee/optee/device.c5
-rw-r--r--include/dt-bindings/arm/qcom,ids.h10
-rw-r--r--include/dt-bindings/reset/cix,sky1-s5-system-control.h163
-rw-r--r--include/dt-bindings/reset/cix,sky1-system-control.h41
-rw-r--r--include/linux/bus/stm32_firewall.h (renamed from drivers/bus/stm32_firewall.h)0
-rw-r--r--include/linux/bus/stm32_firewall_device.h26
-rw-r--r--include/linux/firmware/samsung/exynos-acpm-protocol.h40
-rw-r--r--include/linux/reset-controller.h21
-rw-r--r--include/linux/reset.h43
-rw-r--r--include/linux/soc/qcom/llcc-qcom.h8
-rw-r--r--include/linux/soc/qcom/qmi.h12
-rw-r--r--include/linux/soc/qcom/ubwc.h25
-rw-r--r--include/linux/tee_core.h30
-rw-r--r--include/soc/tegra/bpmp-abi.h4573
-rw-r--r--include/soc/tegra/bpmp.h20
-rw-r--r--include/soc/tegra/mc.h40
-rw-r--r--samples/qmi/qmi_sample_client.c2
148 files changed, 9023 insertions, 2636 deletions
diff --git a/Documentation/devicetree/bindings/arm/arm,coresight-cti.yaml b/Documentation/devicetree/bindings/arm/arm,coresight-cti.yaml
index 2a91670ccb8c..949444aba1f8 100644
--- a/Documentation/devicetree/bindings/arm/arm,coresight-cti.yaml
+++ b/Documentation/devicetree/bindings/arm/arm,coresight-cti.yaml
@@ -128,6 +128,9 @@ properties:
"#address-cells":
const: 1
+ access-controllers:
+ maxItems: 1
+
patternProperties:
'^trig-conns@([0-9]+)$':
type: object
diff --git a/Documentation/devicetree/bindings/arm/arm,coresight-dynamic-funnel.yaml b/Documentation/devicetree/bindings/arm/arm,coresight-dynamic-funnel.yaml
index b74db15e5f8a..b0693cd46d27 100644
--- a/Documentation/devicetree/bindings/arm/arm,coresight-dynamic-funnel.yaml
+++ b/Documentation/devicetree/bindings/arm/arm,coresight-dynamic-funnel.yaml
@@ -78,6 +78,9 @@ properties:
description: Output connection to CoreSight Trace bus
$ref: /schemas/graph.yaml#/properties/port
+ access-controllers:
+ maxItems: 1
+
required:
- compatible
- reg
diff --git a/Documentation/devicetree/bindings/arm/arm,coresight-etm.yaml b/Documentation/devicetree/bindings/arm/arm,coresight-etm.yaml
index 71f2e1ed27e5..10ebbbeadf93 100644
--- a/Documentation/devicetree/bindings/arm/arm,coresight-etm.yaml
+++ b/Documentation/devicetree/bindings/arm/arm,coresight-etm.yaml
@@ -118,6 +118,9 @@ properties:
description: Output connection from the ETM to CoreSight Trace bus.
$ref: /schemas/graph.yaml#/properties/port
+ access-controllers:
+ maxItems: 1
+
required:
- compatible
- clocks
diff --git a/Documentation/devicetree/bindings/arm/arm,coresight-stm.yaml b/Documentation/devicetree/bindings/arm/arm,coresight-stm.yaml
index 378380c3f5aa..f243e76f597f 100644
--- a/Documentation/devicetree/bindings/arm/arm,coresight-stm.yaml
+++ b/Documentation/devicetree/bindings/arm/arm,coresight-stm.yaml
@@ -73,6 +73,9 @@ properties:
description: Output connection to the CoreSight Trace bus.
$ref: /schemas/graph.yaml#/properties/port
+ access-controllers:
+ maxItems: 1
+
required:
- compatible
- reg
diff --git a/Documentation/devicetree/bindings/arm/arm,coresight-tmc.yaml b/Documentation/devicetree/bindings/arm/arm,coresight-tmc.yaml
index 96dd5b5f771a..9dc096698c65 100644
--- a/Documentation/devicetree/bindings/arm/arm,coresight-tmc.yaml
+++ b/Documentation/devicetree/bindings/arm/arm,coresight-tmc.yaml
@@ -128,6 +128,9 @@ properties:
- const: tracedata
- const: metadata
+ access-controllers:
+ maxItems: 1
+
required:
- compatible
- reg
diff --git a/Documentation/devicetree/bindings/arm/arm,coresight-tpiu.yaml b/Documentation/devicetree/bindings/arm/arm,coresight-tpiu.yaml
index a207f6899e67..29bbc3961fdf 100644
--- a/Documentation/devicetree/bindings/arm/arm,coresight-tpiu.yaml
+++ b/Documentation/devicetree/bindings/arm/arm,coresight-tpiu.yaml
@@ -70,6 +70,9 @@ properties:
description: Input connection from the CoreSight Trace bus.
$ref: /schemas/graph.yaml#/properties/port
+ access-controllers:
+ maxItems: 1
+
required:
- compatible
- reg
diff --git a/Documentation/devicetree/bindings/arm/atmel,at91rm9200-sdramc.yaml b/Documentation/devicetree/bindings/arm/atmel,at91rm9200-sdramc.yaml
new file mode 100644
index 000000000000..ac7e0f454a34
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/atmel,at91rm9200-sdramc.yaml
@@ -0,0 +1,66 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/arm/atmel,at91rm9200-sdramc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Microchip (Atmel) SDRAM / DDR Controller (RAMC / DDRAMC / UDDRC)
+
+maintainers:
+ - Nicolas Ferre <nicolas.ferre@microchip.com>
+ - Claudiu Beznea <claudiu.beznea@tuxon.dev>
+
+description:
+ The SDRAM/DDR Controller (often called RAMC or DDRAMC) in various
+ Atmel/Microchip ARM9 and Cortex-A5/A7 SoCs manages external
+ SDRAM / DDR memory. It is typically exposed as a syscon node for
+ register access from other drivers (e.g. for initialization or mode
+ configuration). No interrupts or clocks are usually required in the
+ binding.
+
+properties:
+ compatible:
+ oneOf:
+ - items:
+ - const: atmel,at91rm9200-sdramc
+ - const: syscon
+ - items:
+ - const: microchip,sama7d65-uddrc
+ - const: microchip,sama7g5-uddrc
+ - enum:
+ - atmel,at91sam9260-sdramc
+ - atmel,at91sam9g45-ddramc
+ - atmel,sama5d3-ddramc
+ - microchip,sam9x60-ddramc
+ - microchip,sam9x7-ddramc
+ - microchip,sama7g5-uddrc
+
+ reg:
+ maxItems: 1
+
+ clocks:
+ minItems: 1
+ maxItems: 2
+
+ clock-names:
+ minItems: 1
+ items:
+ - const: ddrck
+ - const: mpddr
+
+required:
+ - compatible
+ - reg
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/at91.h>
+ ramc@ffffe400 {
+ compatible = "atmel,at91sam9g45-ddramc";
+ reg = <0xffffe400 0x200>;
+ clocks = <&pmc PMC_TYPE_SYSTEM 2>;
+ clock-names = "ddrck";
+ };
+...
diff --git a/Documentation/devicetree/bindings/arm/atmel,at91rm9200-st.yaml b/Documentation/devicetree/bindings/arm/atmel,at91rm9200-st.yaml
new file mode 100644
index 000000000000..3f6a934a2a69
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/atmel,at91rm9200-st.yaml
@@ -0,0 +1,69 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/arm/atmel,at91rm9200-st.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Atmel System Timer
+
+maintainers:
+ - Nicolas Ferre <nicolas.ferre@microchip.com>
+ - Claudiu Beznea <claudiu.beznea@tuxon.dev>
+
+description:
+ The System Timer (ST) module in AT91RM9200 provides periodic tick and
+ alarm capabilities. It is exposed as a simple multi-function device
+ (simple-mfd + syscon) because it shares its register space and interrupt
+ with other System Controller blocks.
+
+properties:
+ compatible:
+ items:
+ - const: atmel,at91rm9200-st
+ - const: syscon
+ - const: simple-mfd
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ clocks:
+ maxItems: 1
+
+ "#address-cells":
+ const: 1
+
+ "#size-cells":
+ const: 1
+
+patternProperties:
+ "^watchdog@[0-9a-f]+$":
+ $ref: /schemas/watchdog/atmel,at91rm9200-wdt.yaml#
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - clocks
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/irq.h>
+ timer@fffffd00 {
+ compatible = "atmel,at91rm9200-st", "syscon", "simple-mfd";
+ reg = <0xfffffd00 0x100>;
+ interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
+ clocks = <&slow_xtal>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ watchdog@fffffd40 {
+ compatible = "atmel,at91rm9200-wdt";
+ reg = <0xfffffd40 0x40>;
+ };
+ };
+...
diff --git a/Documentation/devicetree/bindings/arm/atmel,at91sam9260-pit.yaml b/Documentation/devicetree/bindings/arm/atmel,at91sam9260-pit.yaml
new file mode 100644
index 000000000000..d1bdc4a4f9e0
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/atmel,at91sam9260-pit.yaml
@@ -0,0 +1,49 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/arm/atmel,at91sam9260-pit.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Atmel AT91SAM9260 Periodic Interval Timer (PIT)
+
+maintainers:
+ - Nicolas Ferre <nicolas.ferre@microchip.com>
+ - Claudiu Beznea <claudiu.beznea@tuxon.dev>
+
+description:
+ The Periodic Interval Timer (PIT) is part of the System Controller of
+ various Microchip 32-bit ARM-based SoCs (formerly Atmel AT91 series).
+ It is a simple down-counter timer used mainly as the kernel tick source.
+ The PIT is clocked from the slow clock and shares a single IRQ line with
+ other System Controller peripherals.
+
+properties:
+ compatible:
+ const: atmel,at91sam9260-pit
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ clocks:
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+ - interrupts
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/irq.h>
+ timer@fffffd30 {
+ compatible = "atmel,at91sam9260-pit";
+ reg = <0xfffffd30 0x10>;
+ interrupts = <1 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk32k>;
+ };
+...
diff --git a/Documentation/devicetree/bindings/arm/atmel-sysregs.txt b/Documentation/devicetree/bindings/arm/atmel-sysregs.txt
deleted file mode 100644
index 5ce54f9befe6..000000000000
--- a/Documentation/devicetree/bindings/arm/atmel-sysregs.txt
+++ /dev/null
@@ -1,48 +0,0 @@
-Atmel system registers
-
-Chipid required properties:
-- compatible: Should be "atmel,sama5d2-chipid" or "microchip,sama7g5-chipid"
- "microchip,sama7d65-chipid"
-- reg : Should contain registers location and length
-
-PIT Timer required properties:
-- compatible: Should be "atmel,at91sam9260-pit"
-- reg: Should contain registers location and length
-- interrupts: Should contain interrupt for the PIT which is the IRQ line
- shared across all System Controller members.
-
-PIT64B Timer required properties:
-- compatible: Should be "microchip,sam9x60-pit64b" or
- "microchip,sam9x7-pit64b", "microchip,sam9x60-pit64b"
- "microchip,sama7d65-pit64b", "microchip,sam9x60-pit64b"
-- reg: Should contain registers location and length
-- interrupts: Should contain interrupt for PIT64B timer
-- clocks: Should contain the available clock sources for PIT64B timer.
-
-System Timer (ST) required properties:
-- compatible: Should be "atmel,at91rm9200-st", "syscon", "simple-mfd"
-- reg: Should contain registers location and length
-- interrupts: Should contain interrupt for the ST which is the IRQ line
- shared across all System Controller members.
-- clocks: phandle to input clock.
-Its subnodes can be:
-- watchdog: compatible should be "atmel,at91rm9200-wdt"
-
-RAMC SDRAM/DDR Controller required properties:
-- compatible: Should be "atmel,at91rm9200-sdramc", "syscon" or
- "atmel,at91sam9260-sdramc" or
- "atmel,at91sam9g45-ddramc" or
- "atmel,sama5d3-ddramc" or
- "microchip,sam9x60-ddramc" or
- "microchip,sama7g5-uddrc" or
- "microchip,sama7d65-uddrc", "microchip,sama7g5-uddrc" or
- "microchip,sam9x7-ddramc", "atmel,sama5d3-ddramc".
-- reg: Should contain registers location and length
-
-Examples:
-
- ramc0: ramc@ffffe800 {
- compatible = "atmel,at91sam9g45-ddramc";
- reg = <0xffffe800 0x200>;
- };
-
diff --git a/Documentation/devicetree/bindings/arm/freescale/fsl,imx7ulp-pm.yaml b/Documentation/devicetree/bindings/arm/freescale/fsl,imx7ulp-pm.yaml
index 9d377e193c12..7ad470260c0d 100644
--- a/Documentation/devicetree/bindings/arm/freescale/fsl,imx7ulp-pm.yaml
+++ b/Documentation/devicetree/bindings/arm/freescale/fsl,imx7ulp-pm.yaml
@@ -28,6 +28,9 @@ properties:
reg:
maxItems: 1
+ '#clock-cells':
+ const: 1
+
clocks:
maxItems: 2
@@ -39,6 +42,7 @@ properties:
required:
- compatible
- reg
+ - '#clock-cells'
additionalProperties: false
@@ -47,4 +51,5 @@ examples:
smc1@40410000 {
compatible = "fsl,imx7ulp-smc1";
reg = <0x40410000 0x1000>;
+ #clock-cells = <1>;
};
diff --git a/Documentation/devicetree/bindings/arm/fsl.yaml b/Documentation/devicetree/bindings/arm/fsl.yaml
index 5716d701292c..0023cd126807 100644
--- a/Documentation/devicetree/bindings/arm/fsl.yaml
+++ b/Documentation/devicetree/bindings/arm/fsl.yaml
@@ -996,6 +996,14 @@ properties:
- const: engicam,icore-mx8mm # i.MX8MM Engicam i.Core MX8M Mini SoM
- const: fsl,imx8mm
+ - description: Ka-Ro Electronics TX8M-1610 based boards
+ items:
+ - enum:
+ - gocontroll,moduline-iv-306-d
+ - gocontroll,moduline-mini-111
+ - const: karo,tx8m-1610
+ - const: fsl,imx8mm
+
- description: Kontron BL i.MX8MM (N801X S) Board
items:
- const: kontron,imx8mm-bl
@@ -1041,6 +1049,13 @@ properties:
- const: phytec,imx8mm-phycore-som # phyCORE-i.MX8MM SoM
- const: fsl,imx8mm
+ - description: SolidRun i.MX8MM SoM based boards
+ items:
+ - enum:
+ - solidrun,imx8mm-hummingboard-ripple # SolidRun i.MX8MM SoM on HummingBoard Ripple
+ - const: solidrun,imx8mm-sr-som
+ - const: fsl,imx8mm
+
- description: Variscite VAR-SOM-MX8MM based boards
items:
- const: variscite,var-som-mx8mm-symphony
@@ -1069,6 +1084,7 @@ properties:
- fsl,imx8mn-ddr4-evk # i.MX8MN DDR4 EVK Board
- fsl,imx8mn-evk # i.MX8MN LPDDR4 EVK Board
- gw,imx8mn-gw7902 # i.MX8MM Gateworks Board
+ - solidrun,solidsense-n8-compact # SolidRun SolidSense N8 Compact
- const: fsl,imx8mn
- description: ifm i.MX8MN VHIP4 based boards
@@ -1106,6 +1122,7 @@ properties:
- beacon,imx8mp-beacon-kit # i.MX8MP Beacon Development Kit
- dmo,imx8mp-data-modul-edm-sbc # i.MX8MP eDM SBC
- emcraft,imx8mp-navqp # i.MX8MP Emcraft Systems NavQ+ Kit
+ - fsl,imx8mp-ab2 # i.MX8MP Audio Board V2
- fsl,imx8mp-evk # i.MX8MP EVK Board
- fsl,imx8mp-evk-revb4 # i.MX8MP EVK Rev B4 Board
- fsl,imx8mp-frdm # i.MX8MP Freedom Board
@@ -1225,6 +1242,7 @@ properties:
items:
- enum:
- solidrun,imx8mp-cubox-m # SolidRun i.MX8MP SoM on CuBox-M
+ - solidrun,imx8mp-hummingboard-iiot # SolidRun i.MX8MP SoM on HummingBoard IIoT
- solidrun,imx8mp-hummingboard-mate # SolidRun i.MX8MP SoM on HummingBoard Mate
- solidrun,imx8mp-hummingboard-pro # SolidRun i.MX8MP SoM on HummingBoard Pro
- solidrun,imx8mp-hummingboard-pulse # SolidRun i.MX8MP SoM on HummingBoard Pulse
@@ -1420,6 +1438,16 @@ properties:
- const: tq,imx8dxp-tqma8xdps # TQ-Systems GmbH TQMa8XDPS SOM
- const: fsl,imx8dxp
+ - description:
+ TQMa8x is a series of SOM featuring NXP i.MX8 system-on-chip
+ variants. It is designed to be clicked on different carrier boards
+ MBa8x is the starterkit
+ items:
+ - enum:
+ - tq,imx8qm-tqma8qm-mba8x # TQ-Systems GmbH TQMa8QM SOM on MBa8x
+ - const: tq,imx8qm-tqma8qm # TQ-Systems GmbH TQMa8QM SOM
+ - const: fsl,imx8qm
+
- description: i.MX8ULP based Boards
items:
- enum:
@@ -1432,6 +1460,7 @@ properties:
- enum:
- fsl,imx91-11x11-evk # i.MX91 11x11 EVK Board
- fsl,imx91-11x11-frdm # FRDM i.MX91 Development Board
+ - fsl,imx91-11x11-frdm-s # FRDM i.MX91S Development Board
- const: fsl,imx91
- description: i.MX93 based Boards
@@ -1441,6 +1470,7 @@ properties:
- fsl,imx93-11x11-evk # i.MX93 11x11 EVK Board
- fsl,imx93-11x11-frdm # i.MX93 11x11 FRDM Board
- fsl,imx93-14x14-evk # i.MX93 14x14 EVK Board
+ - fsl,imx93-wireless-evk # i.MX93 and IW610G WLCSP (Wi-Fi + BLE + 802.15.4) SiP EVK Board
- const: fsl,imx93
- description: i.MX94 based Boards
@@ -1477,6 +1507,36 @@ properties:
- const: toradex,smarc-imx95 # Toradex SMARC iMX95 Module
- const: fsl,imx95
+ - description: Toradex Boards with Verdin iMX95 Modules
+ items:
+ - enum:
+ - toradex,verdin-imx95-nonwifi-dahlia # Verdin iMX95 Module on Dahlia
+ - toradex,verdin-imx95-nonwifi-dev # Verdin iMX95 Module on Verdin Development Board
+ - toradex,verdin-imx95-nonwifi-ivy # Verdin iMX95 Module on Ivy
+ - toradex,verdin-imx95-nonwifi-mallow # Verdin iMX95 Module on Mallow
+ - toradex,verdin-imx95-nonwifi-yavia # Verdin iMX95 Module on Yavia
+ - const: toradex,verdin-imx95-nonwifi # Verdin iMX95 Module without Wi-Fi / BT
+ - const: toradex,verdin-imx95 # Verdin iMX95 Module
+ - const: fsl,imx95
+
+ - description: Toradex Boards with Verdin iMX95 Wi-Fi / BT Modules
+ items:
+ - enum:
+ - toradex,verdin-imx95-wifi-dahlia # Verdin iMX95 Wi-Fi / BT Module on Dahlia
+ - toradex,verdin-imx95-wifi-dev # Verdin iMX95 Wi-Fi / BT Module on Verdin Development B.
+ - toradex,verdin-imx95-wifi-ivy # Verdin iMX95 Wi-Fi / BT Module on Ivy
+ - toradex,verdin-imx95-wifi-mallow # Verdin iMX95 Wi-Fi / BT Module on Mallow
+ - toradex,verdin-imx95-wifi-yavia # Verdin iMX95 Wi-Fi / BT Module on Yavia
+ - const: toradex,verdin-imx95-wifi # Verdin iMX95 Wi-Fi / BT Module
+ - const: toradex,verdin-imx95 # Verdin iMX95 Module
+ - const: fsl,imx95
+
+ - description: Variscite DART-MX95 based Boards
+ items:
+ - const: variscite,var-dart-mx95-sonata # Variscite DART-MX95 SOM on Sonata Development Board
+ - const: variscite,var-dart-mx95 # Variscite DART-MX95 SOM
+ - const: fsl,imx95
+
- description: i.MXRT1050 based Boards
items:
- enum:
@@ -1522,11 +1582,14 @@ properties:
soldered on an adapter board or for the connector variant
MBa93xxLA mainboard is a single board computer using the solderable
SOM variant
+ MBa93xxLA-MINI mainboard is a single board computer using the solderable
+ SOM variant
items:
- enum:
- tq,imx93-tqma9352-mba91xxca # TQ-Systems GmbH i.MX93 TQMa93xxCA/LA SOM on MBa91xxCA
- tq,imx93-tqma9352-mba93xxca # TQ-Systems GmbH i.MX93 TQMa93xxCA/LA SOM on MBa93xxCA
- tq,imx93-tqma9352-mba93xxla # TQ-Systems GmbH i.MX93 TQMa93xxLA SOM on MBa93xxLA SBC
+ - tq,imx93-tqma9352-mba93xxla-mini # TQ-Systems GmbH i.MX93 TQMa93xxLA SOM on MBa93xxLA-MINI SBC
- const: tq,imx93-tqma9352 # TQ-Systems GmbH i.MX93 TQMa93xxCA/LA SOM
- const: fsl,imx93
@@ -1545,6 +1608,12 @@ properties:
- const: phytec,imx93-phycore-som # phyCORE-i.MX93 SoM
- const: fsl,imx93
+ - description: Variscite DART-MX91 based boards
+ items:
+ - const: variscite,var-dart-mx91-sonata # Variscite DART-MX91 on Sonata Development Board
+ - const: variscite,var-dart-mx91 # Variscite DART-MX91 SOM
+ - const: fsl,imx91
+
- description: Variscite VAR-SOM-MX93 based boards
items:
- const: variscite,var-som-mx93-symphony
@@ -1558,6 +1627,17 @@ properties:
- const: fsl,imx93
- description:
+ TQMa95xxLA is a series of SOM featuring NXP i.MX95 SoC variants,
+ designed to be soldered on different carrier boards.
+ MBa95xxCA is a carrier reference design / starter kit that allows
+ to use TQMa95xxLA via an adaper board.
+ items:
+ - enum:
+ - tq,imx95-tqma9596la-mba95xxca # TQ-Systems GmbH i.MX95 TQMa95xxLA SOM on MBa95xxCA
+ - const: tq,imx95-tqma9596la # TQ-Systems GmbH i.MX95 TQMa95xxLA SOM
+ - const: fsl,imx95
+
+ - description:
TQMa95xxSA is a series of SOM featuring NXP i.MX95 SoC variants.
It has the SMARC form factor and is designed to be placed on
different carrier boards. MB-SMARC-2 is a carrier reference design.
@@ -1827,6 +1907,12 @@ properties:
- fsl,s32v234-evb # S32V234-EVB2 Customer Evaluation Board
- const: fsl,s32v234
+ - description: S32N79 based Boards
+ items:
+ - enum:
+ - nxp,s32n79-rdb
+ - const: nxp,s32n79
+
- description: Traverse LS1088A based Boards
items:
- enum:
diff --git a/Documentation/devicetree/bindings/arm/microchip,sam9x60-pit64b.yaml b/Documentation/devicetree/bindings/arm/microchip,sam9x60-pit64b.yaml
new file mode 100644
index 000000000000..802cf2424c42
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/microchip,sam9x60-pit64b.yaml
@@ -0,0 +1,68 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/arm/microchip,sam9x60-pit64b.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Microchip PIT64B 64-bit Periodic Interval Timer
+
+maintainers:
+ - Nicolas Ferre <nicolas.ferre@microchip.com>
+ - Claudiu Beznea <claudiu.beznea@tuxon.dev>
+
+description:
+ The Microchip PIT64B is a 64-bit periodic interval timer used in
+ several modern Microchip ARM SoCs including SAM9X60, SAM9X7 and
+ SAMA7D65 families. It provides extended timing range, flexible
+ clock selection and supports both periodic and one-shot interrupt
+ generation modes.
+
+properties:
+ compatible:
+ oneOf:
+ - const: microchip,sam9x60-pit64b
+ - items:
+ - enum:
+ - microchip,sam9x7-pit64b
+ - microchip,sama7d65-pit64b
+ - microchip,sama7g5-pit64b
+ - const: microchip,sam9x60-pit64b
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ clocks:
+ minItems: 1
+ maxItems: 2
+
+ clock-names:
+ minItems: 1
+ maxItems: 2
+ items:
+ enum:
+ - pclk
+ - gclk
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - clocks
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/irq.h>
+ #include <dt-bindings/clock/at91.h>
+ timer@f0028000 {
+ compatible = "microchip,sama7g5-pit64b", "microchip,sam9x60-pit64b";
+ reg = <0xf0028000 0x100>;
+ interrupts = <37 IRQ_TYPE_LEVEL_HIGH 7>;
+ clocks = <&pmc PMC_TYPE_PERIPHERAL 37>, <&pmc PMC_TYPE_GCK 37>;
+ clock-names = "pclk", "gclk";
+ };
+...
diff --git a/Documentation/devicetree/bindings/arm/microchip,sama7g5-chipid.yaml b/Documentation/devicetree/bindings/arm/microchip,sama7g5-chipid.yaml
new file mode 100644
index 000000000000..4d6442ba5ac9
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/microchip,sama7g5-chipid.yaml
@@ -0,0 +1,41 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/arm/microchip,sama7g5-chipid.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Atmel/Microchip RAMC SDRAM/DDR Controller
+
+maintainers:
+ - Nicolas Ferre <nicolas.ferre@microchip.com>
+ - Claudiu Beznea <claudiu.beznea@tuxon.dev>
+
+description:
+ This binding describes the Atmel/Microchip Chip ID register block used
+ for SoC identification and revision information. It requires compatible
+ strings matching specific SoC families and a reg property defining the
+ register address and size.
+
+properties:
+ compatible:
+ enum:
+ - atmel,sama5d2-chipid
+ - microchip,sama7d65-chipid
+ - microchip,sama7g5-chipid
+
+ reg:
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ chipid@fc069000 {
+ compatible = "atmel,sama5d2-chipid";
+ reg = <0xfc069000 0x8>;
+ };
+...
diff --git a/Documentation/devicetree/bindings/arm/nxp/lpc32xx.yaml b/Documentation/devicetree/bindings/arm/nxp/lpc32xx.yaml
index 6b7f5e6f99cf..1e290f16a7a5 100644
--- a/Documentation/devicetree/bindings/arm/nxp/lpc32xx.yaml
+++ b/Documentation/devicetree/bindings/arm/nxp/lpc32xx.yaml
@@ -22,5 +22,27 @@ properties:
- phytec,phy3250
- const: nxp,lpc3250
+ - items:
+ - enum:
+ - ea,lpc4357-developers-kit
+ - const: nxp,lpc4357
+ - const: nxp,lpc4350
+
+ - items:
+ - enum:
+ - ciaa,lpc4337
+ - const: nxp,lpc4337
+ - const: nxp,lpc4350
+
+ - items:
+ - enum:
+ - hitex,lpc4350-eval-board
+ - const: nxp,lpc4350
+
+ - items:
+ - enum:
+ - myir,myd-lpc4357
+ - const: nxp,lpc4357
+
additionalProperties: true
...
diff --git a/Documentation/devicetree/bindings/arm/tegra.yaml b/Documentation/devicetree/bindings/arm/tegra.yaml
index 50a31dba7bec..033a63f6c068 100644
--- a/Documentation/devicetree/bindings/arm/tegra.yaml
+++ b/Documentation/devicetree/bindings/arm/tegra.yaml
@@ -132,6 +132,33 @@ properties:
- const: toradex,apalis-tk1
- const: nvidia,tegra124
- items:
+ - const: google,nyan-big-rev7
+ - const: google,nyan-big-rev6
+ - const: google,nyan-big-rev5
+ - const: google,nyan-big-rev4
+ - const: google,nyan-big-rev3
+ - const: google,nyan-big-rev2
+ - const: google,nyan-big-rev1
+ - const: google,nyan-big-rev0
+ - const: google,nyan-big
+ - const: google,nyan
+ - const: nvidia,tegra124
+ - items:
+ - const: google,nyan-blaze-rev10
+ - const: google,nyan-blaze-rev9
+ - const: google,nyan-blaze-rev8
+ - const: google,nyan-blaze-rev7
+ - const: google,nyan-blaze-rev6
+ - const: google,nyan-blaze-rev5
+ - const: google,nyan-blaze-rev4
+ - const: google,nyan-blaze-rev3
+ - const: google,nyan-blaze-rev2
+ - const: google,nyan-blaze-rev1
+ - const: google,nyan-blaze-rev0
+ - const: google,nyan-blaze
+ - const: google,nyan
+ - const: nvidia,tegra124
+ - items:
- enum:
- nvidia,norrin
- const: nvidia,tegra132
@@ -184,17 +211,35 @@ properties:
- const: nvidia,tegra124
- items:
- enum:
- - nvidia,darcy
- nvidia,p2371-0000
- nvidia,p2371-2180
- nvidia,p2571
- - nvidia,p2894-0050-a08
- - nvidia,p3450-0000
- const: nvidia,tegra210
- items:
- const: nvidia,p3541-0000
- const: nvidia,p3450-0000
- const: nvidia,tegra210
+ - description: NVIDIA Jetson Nano
+ items:
+ - const: nvidia,p3450-0000
+ - const: nvidia,tegra210
+ - description: NVIDIA Shield TV
+ items:
+ - const: nvidia,p2894-0050-a08
+ - const: nvidia,darcy
+ - const: nvidia,tegra210
+ - description: Google Pixel C
+ items:
+ - const: google,smaug-rev8
+ - const: google,smaug-rev7
+ - const: google,smaug-rev6
+ - const: google,smaug-rev5
+ - const: google,smaug-rev4
+ - const: google,smaug-rev3
+ - const: google,smaug-rev2
+ - const: google,smaug-rev1
+ - const: google,smaug
+ - const: nvidia,tegra210
- description: Jetson TX2 Developer Kit
items:
- const: nvidia,p2771-0000
@@ -268,5 +313,10 @@ properties:
- const: nvidia,p3971-0089+p3834-0008
- const: nvidia,p3834-0008
- const: nvidia,tegra264
+ - description: Jetson AGX Thor Developer Kit
+ items:
+ - const: nvidia,p4071-0000+p3834-0008
+ - const: nvidia,p3834-0008
+ - const: nvidia,tegra264
additionalProperties: true
diff --git a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra234-cbb.yaml b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra234-cbb.yaml
index fcdf03131323..e69ee6a48fcc 100644
--- a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra234-cbb.yaml
+++ b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra234-cbb.yaml
@@ -48,6 +48,10 @@ properties:
- nvidia,tegra234-dce-fabric
- nvidia,tegra234-rce-fabric
- nvidia,tegra234-sce-fabric
+ - nvidia,tegra238-ape-fabric
+ - nvidia,tegra238-aon-fabric
+ - nvidia,tegra238-bpmp-fabric
+ - nvidia,tegra238-cbb-fabric
reg:
maxItems: 1
diff --git a/Documentation/devicetree/bindings/bus/st,stm32mp131-dbg-bus.yaml b/Documentation/devicetree/bindings/bus/st,stm32mp131-dbg-bus.yaml
new file mode 100644
index 000000000000..6c74433efbe3
--- /dev/null
+++ b/Documentation/devicetree/bindings/bus/st,stm32mp131-dbg-bus.yaml
@@ -0,0 +1,76 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/bus/st,stm32mp131-dbg-bus.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: STM32 Coresight bus
+
+maintainers:
+ - Gatien Chevallier <gatien.chevallier@foss.st.com>
+
+description:
+ The STM32 debug bus is in charge of checking the debug configuration
+ of the platform before probing the peripheral drivers that rely on the debug
+ domain.
+
+properties:
+ compatible:
+ items:
+ - enum:
+ - st,stm32mp131-dbg-bus
+ - st,stm32mp151-dbg-bus
+
+ "#address-cells":
+ const: 1
+
+ "#size-cells":
+ const: 1
+
+ ranges:
+ minItems: 1
+ maxItems: 2
+
+ "#access-controller-cells":
+ const: 1
+ description:
+ Contains the debug profile necessary to access the peripheral.
+
+patternProperties:
+ "@[0-9a-f]+$":
+ description: Debug related peripherals
+ type: object
+
+ additionalProperties: true
+
+ required:
+ - access-controllers
+
+required:
+ - "#access-controller-cells"
+ - "#address-cells"
+ - "#size-cells"
+ - compatible
+ - ranges
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/stm32mp1-clks.h>
+
+ dbg_bus: bus@50080000 {
+ compatible = "st,stm32mp131-dbg-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ #access-controller-cells = <1>;
+ ranges = <0x50080000 0x50080000 0x3f80000>;
+
+ cti@50094000 {
+ compatible = "arm,coresight-cti", "arm,primecell";
+ reg = <0x50094000 0x1000>;
+ clocks = <&rcc CK_DBG>;
+ clock-names = "apb_pclk";
+ access-controllers = <&dbg_bus 0>;
+ };
+ };
diff --git a/Documentation/devicetree/bindings/cache/baikal,bt1-l2-ctl.yaml b/Documentation/devicetree/bindings/cache/baikal,bt1-l2-ctl.yaml
deleted file mode 100644
index ec4f367bc0b4..000000000000
--- a/Documentation/devicetree/bindings/cache/baikal,bt1-l2-ctl.yaml
+++ /dev/null
@@ -1,63 +0,0 @@
-# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
-# Copyright (C) 2020 BAIKAL ELECTRONICS, JSC
-%YAML 1.2
----
-$id: http://devicetree.org/schemas/cache/baikal,bt1-l2-ctl.yaml#
-$schema: http://devicetree.org/meta-schemas/core.yaml#
-
-title: Baikal-T1 L2-cache Control Block
-
-maintainers:
- - Serge Semin <fancer.lancer@gmail.com>
-
-description: |
- By means of the System Controller Baikal-T1 SoC exposes a few settings to
- tune the MIPS P5600 CM2 L2 cache performance up. In particular it's possible
- to change the Tag, Data and Way-select RAM access latencies. Baikal-T1
- L2-cache controller block is responsible for the tuning. Its DT node is
- supposed to be a child of the system controller.
-
-properties:
- compatible:
- const: baikal,bt1-l2-ctl
-
- reg:
- maxItems: 1
-
- baikal,l2-ws-latency:
- $ref: /schemas/types.yaml#/definitions/uint32
- description: Cycles of latency for Way-select RAM accesses
- default: 0
- minimum: 0
- maximum: 3
-
- baikal,l2-tag-latency:
- $ref: /schemas/types.yaml#/definitions/uint32
- description: Cycles of latency for Tag RAM accesses
- default: 0
- minimum: 0
- maximum: 3
-
- baikal,l2-data-latency:
- $ref: /schemas/types.yaml#/definitions/uint32
- description: Cycles of latency for Data RAM accesses
- default: 1
- minimum: 0
- maximum: 3
-
-additionalProperties: false
-
-required:
- - compatible
-
-examples:
- - |
- l2@1f04d028 {
- compatible = "baikal,bt1-l2-ctl";
- reg = <0x1f04d028 0x004>;
-
- baikal,l2-ws-latency = <1>;
- baikal,l2-tag-latency = <1>;
- baikal,l2-data-latency = <2>;
- };
-...
diff --git a/Documentation/devicetree/bindings/cache/qcom,llcc.yaml b/Documentation/devicetree/bindings/cache/qcom,llcc.yaml
index 6671e461e34a..995d57815781 100644
--- a/Documentation/devicetree/bindings/cache/qcom,llcc.yaml
+++ b/Documentation/devicetree/bindings/cache/qcom,llcc.yaml
@@ -33,6 +33,7 @@ properties:
- qcom,sc7280-llcc
- qcom,sc8180x-llcc
- qcom,sc8280xp-llcc
+ - qcom,sdm670-llcc
- qcom,sdm845-llcc
- qcom,sm6350-llcc
- qcom,sm7150-llcc
@@ -204,6 +205,7 @@ allOf:
contains:
enum:
- qcom,sc7280-llcc
+ - qcom,sdm670-llcc
then:
properties:
reg:
diff --git a/Documentation/devicetree/bindings/clock/nvidia,tegra124-dfll.txt b/Documentation/devicetree/bindings/clock/nvidia,tegra124-dfll.txt
deleted file mode 100644
index f7d347385b57..000000000000
--- a/Documentation/devicetree/bindings/clock/nvidia,tegra124-dfll.txt
+++ /dev/null
@@ -1,155 +0,0 @@
-NVIDIA Tegra124 DFLL FCPU clocksource
-
-This binding uses the common clock binding:
-Documentation/devicetree/bindings/clock/clock-bindings.txt
-
-The DFLL IP block on Tegra is a root clocksource designed for clocking
-the fast CPU cluster. It consists of a free-running voltage controlled
-oscillator connected to the CPU voltage rail (VDD_CPU), and a closed loop
-control module that will automatically adjust the VDD_CPU voltage by
-communicating with an off-chip PMIC either via an I2C bus or via PWM signals.
-
-Required properties:
-- compatible : should be one of:
- - "nvidia,tegra124-dfll": for Tegra124
- - "nvidia,tegra210-dfll": for Tegra210
-- reg : Defines the following set of registers, in the order listed:
- - registers for the DFLL control logic.
- - registers for the I2C output logic.
- - registers for the integrated I2C master controller.
- - look-up table RAM for voltage register values.
-- interrupts: Should contain the DFLL block interrupt.
-- clocks: Must contain an entry for each entry in clock-names.
- See clock-bindings.txt for details.
-- clock-names: Must include the following entries:
- - soc: Clock source for the DFLL control logic.
- - ref: The closed loop reference clock
- - i2c: Clock source for the integrated I2C master.
-- resets: Must contain an entry for each entry in reset-names.
- See ../reset/reset.txt for details.
-- reset-names: Must include the following entries:
- - dvco: Reset control for the DFLL DVCO.
-- #clock-cells: Must be 0.
-- clock-output-names: Name of the clock output.
-- vdd-cpu-supply: Regulator for the CPU voltage rail that the DFLL
- hardware will start controlling. The regulator will be queried for
- the I2C register, control values and supported voltages.
-
-Required properties for the control loop parameters:
-- nvidia,sample-rate: Sample rate of the DFLL control loop.
-- nvidia,droop-ctrl: See the register CL_DVFS_DROOP_CTRL in the TRM.
-- nvidia,force-mode: See the field DFLL_PARAMS_FORCE_MODE in the TRM.
-- nvidia,cf: Numeric value, see the field DFLL_PARAMS_CF_PARAM in the TRM.
-- nvidia,ci: Numeric value, see the field DFLL_PARAMS_CI_PARAM in the TRM.
-- nvidia,cg: Numeric value, see the field DFLL_PARAMS_CG_PARAM in the TRM.
-
-Optional properties for the control loop parameters:
-- nvidia,cg-scale: Boolean value, see the field DFLL_PARAMS_CG_SCALE in the TRM.
-
-Optional properties for mode selection:
-- nvidia,pwm-to-pmic: Use PWM to control regulator rather then I2C.
-
-Required properties for I2C mode:
-- nvidia,i2c-fs-rate: I2C transfer rate, if using full speed mode.
-
-Required properties for PWM mode:
-- nvidia,pwm-period-nanoseconds: period of PWM square wave in nanoseconds.
-- nvidia,pwm-tristate-microvolts: Regulator voltage in micro volts when PWM
- control is disabled and the PWM output is tristated. Note that this voltage is
- configured in hardware, typically via a resistor divider.
-- nvidia,pwm-min-microvolts: Regulator voltage in micro volts when PWM control
- is enabled and PWM output is low. Hence, this is the minimum output voltage
- that the regulator supports when PWM control is enabled.
-- nvidia,pwm-voltage-step-microvolts: Voltage increase in micro volts
- corresponding to a 1/33th increase in duty cycle. Eg the voltage for 2/33th
- duty cycle would be: nvidia,pwm-min-microvolts +
- nvidia,pwm-voltage-step-microvolts * 2.
-- pinctrl-0: I/O pad configuration when PWM control is enabled.
-- pinctrl-1: I/O pad configuration when PWM control is disabled.
-- pinctrl-names: must include the following entries:
- - dvfs_pwm_enable: I/O pad configuration when PWM control is enabled.
- - dvfs_pwm_disable: I/O pad configuration when PWM control is disabled.
-
-Example for I2C:
-
-clock@70110000 {
- compatible = "nvidia,tegra124-dfll";
- reg = <0 0x70110000 0 0x100>, /* DFLL control */
- <0 0x70110000 0 0x100>, /* I2C output control */
- <0 0x70110100 0 0x100>, /* Integrated I2C controller */
- <0 0x70110200 0 0x100>; /* Look-up table RAM */
- interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&tegra_car TEGRA124_CLK_DFLL_SOC>,
- <&tegra_car TEGRA124_CLK_DFLL_REF>,
- <&tegra_car TEGRA124_CLK_I2C5>;
- clock-names = "soc", "ref", "i2c";
- resets = <&tegra_car TEGRA124_RST_DFLL_DVCO>;
- reset-names = "dvco";
- #clock-cells = <0>;
- clock-output-names = "dfllCPU_out";
- vdd-cpu-supply = <&vdd_cpu>;
-
- nvidia,sample-rate = <12500>;
- nvidia,droop-ctrl = <0x00000f00>;
- nvidia,force-mode = <1>;
- nvidia,cf = <10>;
- nvidia,ci = <0>;
- nvidia,cg = <2>;
-
- nvidia,i2c-fs-rate = <400000>;
-};
-
-Example for PWM:
-
-clock@70110000 {
- compatible = "nvidia,tegra124-dfll";
- reg = <0 0x70110000 0 0x100>, /* DFLL control */
- <0 0x70110000 0 0x100>, /* I2C output control */
- <0 0x70110100 0 0x100>, /* Integrated I2C controller */
- <0 0x70110200 0 0x100>; /* Look-up table RAM */
- interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&tegra_car TEGRA210_CLK_DFLL_SOC>,
- <&tegra_car TEGRA210_CLK_DFLL_REF>,
- <&tegra_car TEGRA124_CLK_I2C5>;;
- clock-names = "soc", "ref", "i2c";
- resets = <&tegra_car TEGRA124_RST_DFLL_DVCO>;
- reset-names = "dvco";
- #clock-cells = <0>;
- clock-output-names = "dfllCPU_out";
-
- nvidia,sample-rate = <25000>;
- nvidia,droop-ctrl = <0x00000f00>;
- nvidia,force-mode = <1>;
- nvidia,cf = <6>;
- nvidia,ci = <0>;
- nvidia,cg = <2>;
-
- nvidia,pwm-min-microvolts = <708000>; /* 708mV */
- nvidia,pwm-period-nanoseconds = <2500>; /* 2.5us */
- nvidia,pwm-to-pmic;
- nvidia,pwm-tristate-microvolts = <1000000>;
- nvidia,pwm-voltage-step-microvolts = <19200>; /* 19.2mV */
-
- pinctrl-names = "dvfs_pwm_enable", "dvfs_pwm_disable";
- pinctrl-0 = <&dvfs_pwm_active_state>;
- pinctrl-1 = <&dvfs_pwm_inactive_state>;
-};
-
-/* pinmux nodes added for completeness. Binding doc can be found in:
- * Documentation/devicetree/bindings/pinctrl/nvidia,tegra210-pinmux.yaml
- */
-
-pinmux: pinmux@700008d4 {
- dvfs_pwm_active_state: dvfs_pwm_active {
- dvfs_pwm_pbb1 {
- nvidia,pins = "dvfs_pwm_pbb1";
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- };
- };
- dvfs_pwm_inactive_state: dvfs_pwm_inactive {
- dvfs_pwm_pbb1 {
- nvidia,pins = "dvfs_pwm_pbb1";
- nvidia,tristate = <TEGRA_PIN_ENABLE>;
- };
- };
-};
diff --git a/Documentation/devicetree/bindings/clock/nvidia,tegra124-dfll.yaml b/Documentation/devicetree/bindings/clock/nvidia,tegra124-dfll.yaml
new file mode 100644
index 000000000000..5d689e48c438
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/nvidia,tegra124-dfll.yaml
@@ -0,0 +1,290 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/nvidia,tegra124-dfll.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NVIDIA Tegra124 (and later) DFLL FCPU clocksource
+
+maintainers:
+ - Thierry Reding <thierry.reding@gmail.com>
+ - Jon Hunter <jonathanh@nvidia.com>
+
+description:
+ The DFLL IP block on Tegra is a root clocksource designed for clocking
+ the fast CPU cluster. It consists of a free-running voltage controlled
+ oscillator connected to the CPU voltage rail (VDD_CPU), and a closed
+ loop control module that will automatically adjust the VDD_CPU voltage
+ by communicating with an off-chip PMIC either via an I2C bus or via
+ PWM signals.
+
+properties:
+ compatible:
+ enum:
+ - nvidia,tegra124-dfll
+ - nvidia,tegra210-dfll
+
+ reg:
+ items:
+ - description: DFLL control logic
+ - description: I2C output logic
+ - description: Integrated I2C controller
+ - description: Look-up table RAM for voltage register values
+
+ interrupts:
+ maxItems: 1
+
+ "#clock-cells":
+ const: 0
+
+ clocks:
+ items:
+ - description: Clock source for the DFLL control logic
+ - description: Closed loop reference clock
+ - description: Clock source for the integrated I2C controller
+
+ clock-names:
+ items:
+ - const: soc
+ - const: ref
+ - const: i2c
+
+ clock-output-names:
+ description: Name of the clock output
+ items:
+ - const: dfllCPU_out
+
+ resets:
+ minItems: 1
+ maxItems: 2
+
+ reset-names:
+ minItems: 1
+ items:
+ - const: dvco
+ - const: dfll
+
+ vdd-cpu-supply:
+ description: Regulator for the CPU voltage rail that the DFLL
+ hardware will start controlling. The regulator will be queried for
+ the I2C register, control values and supported voltages.
+
+ nvidia,sample-rate:
+ description: Sample rate of the DFLL control loop
+ $ref: /schemas/types.yaml#/definitions/uint32
+ minimum: 12500
+ maximum: 25000
+
+ nvidia,droop-ctrl:
+ description: Droop control parameter (CL_DVFS_DROOP_CTRL) in the TRM
+ $ref: /schemas/types.yaml#/definitions/uint32
+
+ nvidia,force-mode:
+ description: See the field DFLL_PARAMS_FORCE_MODE in the TRM
+ $ref: /schemas/types.yaml#/definitions/uint32
+ oneOf:
+ - description: disabled
+ const: 0
+ - description: fixed delay mode
+ const: 1
+ - description: auto mode
+ const: 2
+
+ nvidia,cf:
+ description: Numeric value, see the field DFLL_PARAMS_CF_PARAM in the TRM
+ $ref: /schemas/types.yaml#/definitions/uint32
+ minimum: 0
+ maximum: 63
+
+ nvidia,ci:
+ description: Numeric value, see the field DFLL_PARAMS_CI_PARAM in the TRM
+ $ref: /schemas/types.yaml#/definitions/uint32
+ minimum: 0
+ maximum: 7
+
+ nvidia,cg:
+ description: Numeric value, see the field DFLL_PARAMS_CG_PARAM in the TRM
+ $ref: /schemas/types.yaml#/definitions/uint32
+ minimum: 0
+ maximum: 255
+
+ # optional properties
+ nvidia,cg-scale:
+ description: Boolean value, see the field DFLL_PARAMS_CG_SCALE in the TRM
+ $ref: /schemas/types.yaml#/definitions/flag
+
+ nvidia,pwm-to-pmic:
+ description: Use PWM to control regulator rather than I2C
+ $ref: /schemas/types.yaml#/definitions/flag
+
+ nvidia,i2c-fs-rate:
+ description: I2C transfer rate, if using full speed mode
+ $ref: /schemas/types.yaml#/definitions/uint32
+ enum: [100000, 400000]
+
+ # required properties for PWM mode
+ nvidia,pwm-period-nanoseconds:
+ description: Period of PWM square wave in nanoseconds
+ $ref: /schemas/types.yaml#/definitions/uint32
+ minimum: 1000
+ maximum: 1000000000
+
+ nvidia,pwm-tristate-microvolts:
+ description: Regulator voltage in microvolts when PWM control is disabled
+ and the PWM output is tristated. Note that this voltage is configured in
+ hardware, typically via a resistor divider.
+ $ref: /schemas/types.yaml#/definitions/uint32
+ minimum: 0
+ maximum: 3300000
+
+ nvidia,pwm-min-microvolts:
+ description: Regulator voltage in microvolts when PWM control is enabled
+ and PWM output is low. Hence, this is the minimum output voltage that
+ the regulator supports when PWM control is enabled.
+ $ref: /schemas/types.yaml#/definitions/uint32
+ minimum: 0
+ maximum: 3300000
+
+ nvidia,pwm-voltage-step-microvolts:
+ description: |
+ Voltage increase in micro volts corresponding to a 1/33th increase
+ in duty cycle. For example, the voltage for 2/33th duty cycle would be:
+
+ nvidia,pwm-min-microvolts + nvidia,pwm-voltage-step-microvolts * 2
+ $ref: /schemas/types.yaml#/definitions/uint32
+ minimum: 0
+ maximum: 100000
+
+ pinctrl-0:
+ description: I/O pad configuration when PWM control is enabled
+
+ pinctrl-1:
+ description: I/O pad configuration when PWM control is disabled
+
+ pinctrl-names:
+ items:
+ - const: dvfs_pwm_enable
+ - const: dvfs_pwm_disable
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - "#clock-cells"
+ - clocks
+ - clock-names
+ - clock-output-names
+ - resets
+ - reset-names
+ - nvidia,sample-rate
+ - nvidia,droop-ctrl
+ - nvidia,force-mode
+ - nvidia,cf
+ - nvidia,ci
+ - nvidia,cg
+
+additionalProperties: false
+
+allOf:
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: nvidia,tegra124-dfll
+ then:
+ properties:
+ resets:
+ maxItems: 1
+
+ reset-names:
+ maxItems: 1
+ else:
+ properties:
+ resets:
+ minItems: 2
+
+ reset-names:
+ minItems: 2
+
+ - if:
+ required:
+ - nvidia,pwm-to-pmic
+ then:
+ required:
+ - nvidia,pwm-min-microvolts
+ - nvidia,pwm-period-nanoseconds
+ - nvidia,pwm-tristate-microvolts
+ - nvidia,pwm-voltage-step-microvolts
+ else:
+ required:
+ - vdd-cpu-supply
+
+examples:
+ - |
+ #include <dt-bindings/clock/tegra124-car.h>
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/reset/tegra124-car.h>
+
+ clock@70110000 {
+ compatible = "nvidia,tegra124-dfll";
+ reg = <0x70110000 0x100>, /* DFLL control */
+ <0x70110000 0x100>, /* I2C output control */
+ <0x70110100 0x100>, /* Integrated I2C controller */
+ <0x70110200 0x100>; /* Look-up table RAM */
+ interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA124_CLK_DFLL_SOC>,
+ <&tegra_car TEGRA124_CLK_DFLL_REF>,
+ <&tegra_car TEGRA124_CLK_I2C5>;
+ clock-names = "soc", "ref", "i2c";
+ resets = <&tegra_car TEGRA124_RST_DFLL_DVCO>;
+ reset-names = "dvco";
+ #clock-cells = <0>;
+ clock-output-names = "dfllCPU_out";
+ vdd-cpu-supply = <&vdd_cpu>;
+
+ nvidia,sample-rate = <12500>;
+ nvidia,droop-ctrl = <0x00000f00>;
+ nvidia,force-mode = <1>;
+ nvidia,cf = <10>;
+ nvidia,ci = <0>;
+ nvidia,cg = <2>;
+
+ nvidia,i2c-fs-rate = <400000>;
+ };
+
+ - |
+ #include <dt-bindings/clock/tegra210-car.h>
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/reset/tegra210-car.h>
+
+ clock@70110000 {
+ compatible = "nvidia,tegra210-dfll";
+ reg = <0x70110000 0x100>, /* DFLL control */
+ <0x70110000 0x100>, /* I2C output control */
+ <0x70110100 0x100>, /* Integrated I2C controller */
+ <0x70110200 0x100>; /* Look-up table RAM */
+ interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA210_CLK_DFLL_SOC>,
+ <&tegra_car TEGRA210_CLK_DFLL_REF>,
+ <&tegra_car TEGRA210_CLK_I2C5>;
+ clock-names = "soc", "ref", "i2c";
+ resets = <&tegra_car TEGRA210_RST_DFLL_DVCO>,
+ <&tegra_car 155>;
+ reset-names = "dvco", "dfll";
+ #clock-cells = <0>;
+ clock-output-names = "dfllCPU_out";
+ vdd-cpu-supply = <&vdd_cpu>;
+
+ nvidia,sample-rate = <25000>;
+ nvidia,droop-ctrl = <0x00000f00>;
+ nvidia,force-mode = <1>;
+ nvidia,cf = <6>;
+ nvidia,ci = <0>;
+ nvidia,cg = <2>;
+
+ nvidia,pwm-min-microvolts = <708000>; /* 708mV */
+ nvidia,pwm-period-nanoseconds = <2500>; /* 2.5us */
+ nvidia,pwm-to-pmic;
+ nvidia,pwm-tristate-microvolts = <1000000>;
+ nvidia,pwm-voltage-step-microvolts = <19200>; /* 19.2mV */
+ };
diff --git a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-hdmi.yaml b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-hdmi.yaml
index f77197e4869f..b4bf2662780b 100644
--- a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-hdmi.yaml
+++ b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-hdmi.yaml
@@ -82,6 +82,10 @@ properties:
description: phandle of a display panel
$ref: /schemas/types.yaml#/definitions/phandle
+ port:
+ description: HDMI output port for connection to HDMI connector or bridge
+ $ref: /schemas/graph.yaml#/properties/port
+
"#sound-dai-cells":
const: 0
@@ -97,8 +101,13 @@ required:
- reset-names
- pll-supply
- vdd-supply
- - nvidia,ddc-i2c-bus
- - nvidia,hpd-gpio
+
+anyOf:
+ - required:
+ - nvidia,ddc-i2c-bus
+ - nvidia,hpd-gpio
+ - required:
+ - port
examples:
- |
diff --git a/Documentation/devicetree/bindings/firmware/arm,scmi.yaml b/Documentation/devicetree/bindings/firmware/arm,scmi.yaml
index be817fd9cc34..d06cca9273c4 100644
--- a/Documentation/devicetree/bindings/firmware/arm,scmi.yaml
+++ b/Documentation/devicetree/bindings/firmware/arm,scmi.yaml
@@ -146,6 +146,13 @@ properties:
this platform. If set, the value should be non-zero.
minimum: 1
+ arm,no-completion-irq:
+ type: boolean
+ description:
+ This optional property is intended for hardware that does not generate
+ completion interrupts and can be used to unconditionally enable forced
+ polling mode of operation.
+
arm,smc-id:
$ref: /schemas/types.yaml#/definitions/uint32
description:
@@ -379,6 +386,9 @@ then:
- shmem
else:
+ properties:
+ arm,no-completion-irq: false
+
if:
properties:
compatible:
diff --git a/Documentation/devicetree/bindings/firmware/google,gs101-acpm-ipc.yaml b/Documentation/devicetree/bindings/firmware/google,gs101-acpm-ipc.yaml
index 4a1e3e3c0505..e68f9c3ca5e2 100644
--- a/Documentation/devicetree/bindings/firmware/google,gs101-acpm-ipc.yaml
+++ b/Documentation/devicetree/bindings/firmware/google,gs101-acpm-ipc.yaml
@@ -37,6 +37,7 @@ properties:
maxItems: 1
pmic:
+ deprecated: true
description: Child node describing the main PMIC.
type: object
additionalProperties: true
@@ -45,6 +46,24 @@ properties:
compatible:
const: samsung,s2mpg10-pmic
+ pmic-1:
+ description: Child node describing the main PMIC.
+ type: object
+ additionalProperties: true
+
+ properties:
+ compatible:
+ const: samsung,s2mpg10-pmic
+
+ pmic-2:
+ description: Child node describing the sub PMIC.
+ type: object
+ additionalProperties: true
+
+ properties:
+ compatible:
+ const: samsung,s2mpg11-pmic
+
shmem:
description:
List of phandle pointing to the shared memory (SHM) area. The memory
@@ -62,7 +81,9 @@ additionalProperties: false
examples:
- |
+ #include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
+ #include <dt-bindings/regulator/samsung,s2mpg10-regulator.h>
power-management {
compatible = "google,gs101-acpm-ipc";
@@ -70,10 +91,12 @@ examples:
mboxes = <&ap2apm_mailbox>;
shmem = <&apm_sram>;
- pmic {
+ pmic-1 {
compatible = "samsung,s2mpg10-pmic";
interrupts-extended = <&gpa0 6 IRQ_TYPE_LEVEL_LOW>;
+ vinl3m-supply = <&buck8m>;
+
regulators {
ldo1m {
regulator-name = "vdd_ldo1";
@@ -82,7 +105,13 @@ examples:
regulator-always-on;
};
- // ...
+ ldo20m {
+ regulator-name = "vdd_dmics";
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <1300000>;
+ regulator-always-on;
+ samsung,ext-control = <S2MPG10_EXTCTRL_LDO20M_EN2>;
+ };
buck8m {
regulator-name = "vdd_mif";
@@ -93,4 +122,21 @@ examples:
};
};
};
+
+ pmic-2 {
+ compatible = "samsung,s2mpg11-pmic";
+ interrupts-extended = <&gpa0 7 IRQ_TYPE_LEVEL_LOW>;
+
+ vinl1s-supply = <&buck8m>;
+ vinl2s-supply = <&buck6s>;
+
+ regulators {
+ buckd {
+ regulator-name = "vcc_ufs";
+ regulator-ramp-delay = <6250>;
+ enable-gpios = <&gpp0 1 GPIO_ACTIVE_HIGH>;
+ samsung,ext-control = <S2MPG11_EXTCTRL_UFS_EN>;
+ };
+ };
+ };
};
diff --git a/Documentation/devicetree/bindings/firmware/qcom,scm.yaml b/Documentation/devicetree/bindings/firmware/qcom,scm.yaml
index d66459f1d84e..7918d31f58b4 100644
--- a/Documentation/devicetree/bindings/firmware/qcom,scm.yaml
+++ b/Documentation/devicetree/bindings/firmware/qcom,scm.yaml
@@ -23,15 +23,18 @@ properties:
- enum:
- qcom,scm-apq8064
- qcom,scm-apq8084
+ - qcom,scm-eliza
- qcom,scm-glymur
- qcom,scm-ipq4019
- qcom,scm-ipq5018
+ - qcom,scm-ipq5210
- qcom,scm-ipq5332
- qcom,scm-ipq5424
- qcom,scm-ipq6018
- qcom,scm-ipq806x
- qcom,scm-ipq8074
- qcom,scm-ipq9574
+ - qcom,scm-ipq9650
- qcom,scm-kaanapali
- qcom,scm-mdm9607
- qcom,scm-milos
@@ -204,6 +207,7 @@ allOf:
compatible:
contains:
enum:
+ - qcom,scm-eliza
- qcom,scm-kaanapali
- qcom,scm-milos
- qcom,scm-sm8450
diff --git a/Documentation/devicetree/bindings/interrupt-controller/fsl,irqsteer.yaml b/Documentation/devicetree/bindings/interrupt-controller/fsl,irqsteer.yaml
index 5c768c1e159c..13cd37bf48e4 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/fsl,irqsteer.yaml
+++ b/Documentation/devicetree/bindings/interrupt-controller/fsl,irqsteer.yaml
@@ -12,7 +12,9 @@ maintainers:
properties:
compatible:
oneOf:
- - const: fsl,imx-irqsteer
+ - enum:
+ - fsl,imx-irqsteer
+ - nxp,s32n79-irqsteer
- items:
- enum:
- fsl,imx8m-irqsteer
diff --git a/Documentation/devicetree/bindings/interrupt-controller/nvidia,tegra20-ictlr.yaml b/Documentation/devicetree/bindings/interrupt-controller/nvidia,tegra20-ictlr.yaml
index 074a873880e5..d0c039d14ad2 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/nvidia,tegra20-ictlr.yaml
+++ b/Documentation/devicetree/bindings/interrupt-controller/nvidia,tegra20-ictlr.yaml
@@ -35,11 +35,12 @@ properties:
- enum:
- nvidia,tegra20-ictlr
- nvidia,tegra30-ictlr
+ - nvidia,tegra210-ictlr
reg:
description: Each entry is a block of 32 interrupts
minItems: 4
- maxItems: 5
+ maxItems: 6
interrupt-controller: true
@@ -64,10 +65,28 @@ allOf:
properties:
reg:
maxItems: 4
- else:
+
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: nvidia,tegra30-ictlr
+ then:
properties:
reg:
minItems: 5
+ maxItems: 5
+
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: nvidia,tegra210-ictlr
+ then:
+ properties:
+ reg:
+ minItems: 6
+ maxItems: 6
examples:
- |
diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra210-emc.yaml b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra210-emc.yaml
index 4e4fb4acd7f9..7a653a011f03 100644
--- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra210-emc.yaml
+++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra210-emc.yaml
@@ -52,6 +52,9 @@ properties:
Should contain freqs and voltages and opp-supported-hw property, which
is a bitfield indicating SoC speedo ID mask.
+allOf:
+ - $ref: /schemas/thermal/thermal-cooling-devices.yaml
+
required:
- compatible
- reg
@@ -59,7 +62,7 @@ required:
- clock-names
- nvidia,memory-controller
-additionalProperties: false
+unevaluatedProperties: false
examples:
- |
@@ -90,4 +93,5 @@ examples:
operating-points-v2 = <&dvfs_opp_table>;
#interconnect-cells = <0>;
+ #cooling-cells = <2>;
};
diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra210-mc.yaml b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra210-mc.yaml
new file mode 100644
index 000000000000..268d5ff958f9
--- /dev/null
+++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra210-mc.yaml
@@ -0,0 +1,77 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/memory-controllers/nvidia,tegra210-mc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NVIDIA Tegra210 SoC Memory Controller
+
+maintainers:
+ - Thierry Reding <thierry.reding@gmail.com>
+ - Jon Hunter <jonathanh@nvidia.com>
+
+description: |
+ The NVIDIA Tegra210 SoC features a 64 bit memory controller that is split
+ into two 32 bit channels to support LPDDR3 and LPDDR4 with x16 subpartitions.
+ The MC handles memory requests for 34-bit virtual addresses from internal
+ clients and arbitrates among them to allocate memory bandwidth.
+
+ Up to 8 GiB of physical memory can be supported. Security features such as
+ encryption of traffic to and from DRAM via general security apertures are
+ available for video and other secure applications.
+
+properties:
+ $nodename:
+ pattern: "^memory-controller@[0-9a-f]+$"
+
+ compatible:
+ items:
+ - enum:
+ - nvidia,tegra210-mc
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ clocks:
+ items:
+ - description: module clock
+
+ clock-names:
+ items:
+ - const: mc
+
+ "#iommu-cells":
+ const: 1
+
+ "#reset-cells":
+ const: 1
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - clocks
+ - clock-names
+ - "#iommu-cells"
+ - "#reset-cells"
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/tegra210-car.h>
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+ memory-controller@70019000 {
+ compatible = "nvidia,tegra210-mc";
+ reg = <0x70019000 0x1000>;
+ interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA210_CLK_MC>;
+ clock-names = "mc";
+
+ #iommu-cells = <1>;
+ #reset-cells = <1>;
+ };
diff --git a/Documentation/devicetree/bindings/phy/nvidia,tegra194-xusb-padctl.yaml b/Documentation/devicetree/bindings/phy/nvidia,tegra194-xusb-padctl.yaml
index 6e3398399628..d8de900a4fce 100644
--- a/Documentation/devicetree/bindings/phy/nvidia,tegra194-xusb-padctl.yaml
+++ b/Documentation/devicetree/bindings/phy/nvidia,tegra194-xusb-padctl.yaml
@@ -230,6 +230,10 @@ properties:
connector:
type: object
+ port:
+ description: connection to a USB Type C controller
+ $ref: /schemas/graph.yaml#/properties/port
+
mode:
description: A string that determines the mode in which to
run the port.
@@ -256,7 +260,12 @@ properties:
voltage.
dependencies:
- usb-role-switch: [ connector ]
+ usb-role-switch:
+ oneOf:
+ - required:
+ - connector
+ - required:
+ - port
usb2-1:
type: object
@@ -268,6 +277,10 @@ properties:
connector:
type: object
+ port:
+ description: connection to a USB Type C controller
+ $ref: /schemas/graph.yaml#/properties/port
+
mode:
description: A string that determines the mode in which to
run the port.
@@ -306,6 +319,10 @@ properties:
connector:
type: object
+ port:
+ description: connection to a USB Type C controller
+ $ref: /schemas/graph.yaml#/properties/port
+
mode:
description: A string that determines the mode in which to
run the port.
@@ -344,6 +361,10 @@ properties:
connector:
type: object
+ port:
+ description: connection to a USB Type C controller
+ $ref: /schemas/graph.yaml#/properties/port
+
mode:
description: A string that determines the mode in which to
run the port.
@@ -405,6 +426,10 @@ properties:
description: A phandle to the regulator supplying the VBUS
voltage.
+ port:
+ description: connection to a USB Type C controller
+ $ref: /schemas/graph.yaml#/properties/port
+
usb3-1:
type: object
additionalProperties: false
@@ -438,6 +463,10 @@ properties:
description: A phandle to the regulator supplying the VBUS
voltage.
+ port:
+ description: connection to a USB Type C controller
+ $ref: /schemas/graph.yaml#/properties/port
+
usb3-2:
type: object
additionalProperties: false
@@ -471,6 +500,10 @@ properties:
description: A phandle to the regulator supplying the VBUS
voltage.
+ port:
+ description: connection to a USB Type C controller
+ $ref: /schemas/graph.yaml#/properties/port
+
usb3-3:
type: object
additionalProperties: false
@@ -504,6 +537,10 @@ properties:
description: A phandle to the regulator supplying the VBUS
voltage.
+ port:
+ description: connection to a USB Type C controller
+ $ref: /schemas/graph.yaml#/properties/port
+
additionalProperties: false
required:
diff --git a/Documentation/devicetree/bindings/phy/nvidia,tegra20-usb-phy.yaml b/Documentation/devicetree/bindings/phy/nvidia,tegra20-usb-phy.yaml
index d61585c96e31..a37e8322dc50 100644
--- a/Documentation/devicetree/bindings/phy/nvidia,tegra20-usb-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/nvidia,tegra20-usb-phy.yaml
@@ -16,6 +16,7 @@ properties:
oneOf:
- items:
- enum:
+ - nvidia,tegra210-usb-phy
- nvidia,tegra124-usb-phy
- nvidia,tegra114-usb-phy
- enum:
diff --git a/Documentation/devicetree/bindings/pinctrl/st,stm32-hdp.yaml b/Documentation/devicetree/bindings/pinctrl/st,stm32-hdp.yaml
index 845b6b7b7552..8f8b4b68aaa3 100644
--- a/Documentation/devicetree/bindings/pinctrl/st,stm32-hdp.yaml
+++ b/Documentation/devicetree/bindings/pinctrl/st,stm32-hdp.yaml
@@ -27,6 +27,12 @@ properties:
clocks:
maxItems: 1
+ access-controllers:
+ minItems: 1
+ items:
+ - description: debug configuration access controller
+ - description: access controller that manages the HDP as a peripheral
+
patternProperties:
"^hdp[0-7]-pins$":
type: object
diff --git a/Documentation/devicetree/bindings/reset/renesas,rzv2h-usb2phy-reset.yaml b/Documentation/devicetree/bindings/reset/renesas,rzv2h-usb2phy-reset.yaml
index c1b800a10b53..66650ef8f772 100644
--- a/Documentation/devicetree/bindings/reset/renesas,rzv2h-usb2phy-reset.yaml
+++ b/Documentation/devicetree/bindings/reset/renesas,rzv2h-usb2phy-reset.yaml
@@ -17,7 +17,9 @@ properties:
compatible:
oneOf:
- items:
- - const: renesas,r9a09g056-usb2phy-reset # RZ/V2N
+ - enum:
+ - renesas,r9a09g047-usb2phy-reset # RZ/G3E
+ - renesas,r9a09g056-usb2phy-reset # RZ/V2N
- const: renesas,r9a09g057-usb2phy-reset
- const: renesas,r9a09g057-usb2phy-reset # RZ/V2H(P)
@@ -37,6 +39,9 @@ properties:
'#reset-cells':
const: 0
+ '#mux-state-cells':
+ const: 1
+
required:
- compatible
- reg
@@ -44,6 +49,7 @@ required:
- resets
- power-domains
- '#reset-cells'
+ - '#mux-state-cells'
additionalProperties: false
@@ -58,4 +64,5 @@ examples:
resets = <&cpg 0xaf>;
power-domains = <&cpg>;
#reset-cells = <0>;
+ #mux-state-cells = <1>;
};
diff --git a/Documentation/devicetree/bindings/soc/cix/cix,sky1-system-control.yaml b/Documentation/devicetree/bindings/soc/cix/cix,sky1-system-control.yaml
new file mode 100644
index 000000000000..a01a515222c6
--- /dev/null
+++ b/Documentation/devicetree/bindings/soc/cix/cix,sky1-system-control.yaml
@@ -0,0 +1,42 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/soc/cix/cix,sky1-system-control.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Cix Sky1 SoC system control register region
+
+maintainers:
+ - Gary Yang <gary.yang@cixtech.com>
+
+description:
+ An wide assortment of registers of the system controller on Sky1 SoC,
+ including resets, usb, wakeup sources and so on.
+
+properties:
+ compatible:
+ items:
+ - enum:
+ - cix,sky1-system-control
+ - cix,sky1-s5-system-control
+ - const: syscon
+
+ reg:
+ maxItems: 1
+
+ '#reset-cells':
+ const: 1
+
+required:
+ - compatible
+ - reg
+
+additionalProperties: false
+
+examples:
+ - |
+ syscon@4160000 {
+ compatible = "cix,sky1-system-control", "syscon";
+ reg = <0x4160000 0x100>;
+ #reset-cells = <1>;
+ };
diff --git a/Documentation/devicetree/bindings/soc/imx/fsl,imx93-media-blk-ctrl.yaml b/Documentation/devicetree/bindings/soc/imx/fsl,imx93-media-blk-ctrl.yaml
index 34aea58094e5..d828c2e82965 100644
--- a/Documentation/devicetree/bindings/soc/imx/fsl,imx93-media-blk-ctrl.yaml
+++ b/Documentation/devicetree/bindings/soc/imx/fsl,imx93-media-blk-ctrl.yaml
@@ -40,6 +40,58 @@ properties:
minItems: 8
maxItems: 10
+ dpi-bridge:
+ type: object
+ additionalProperties: false
+
+ properties:
+ compatible:
+ enum:
+ - nxp,imx91-pdfc
+ - nxp,imx93-pdfc
+
+ ports:
+ $ref: /schemas/graph.yaml#/properties/ports
+
+ properties:
+ port@0:
+ $ref: /schemas/graph.yaml#/properties/port
+ description: Input port node to receive pixel data.
+
+ port@1:
+ $ref: /schemas/graph.yaml#/$defs/port-base
+ unevaluatedProperties: false
+ description: Output port node to downstream pixel data receivers.
+
+ properties:
+ endpoint:
+ $ref: /schemas/media/video-interfaces.yaml#
+ unevaluatedProperties: false
+
+ properties:
+ bus-width:
+ enum: [ 16, 18, 24 ]
+ description:
+ Specify the physical parallel bus width.
+
+ This property is optional if the display bus-width
+ matches the SoC bus-width, e.g. a 18-bit RGB666 (display)
+ is connected and all 18-bit data lines are muxed to the
+ parallel-output pads.
+
+ This property must be set to 18 to cut only the LSBs
+ instead of the MSBs in case a 24-bit RGB888 display is
+ connected and only the lower 18-bit data lanes are muxed
+ to the parallel-output pads.
+
+ required:
+ - port@0
+ - port@1
+
+ required:
+ - compatible
+ - ports
+
allOf:
- if:
properties:
@@ -112,4 +164,30 @@ examples:
clock-names = "apb", "axi", "nic", "disp", "cam",
"pxp", "lcdif", "isi", "csi", "dsi";
#power-domain-cells = <1>;
+
+ dpi-bridge {
+ compatible = "nxp,imx93-pdfc";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ pdfc_from_lcdif: endpoint {
+ remote-endpoint = <&lcdif_to_pdfc>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ pdfc_to_panel: endpoint {
+ remote-endpoint = <&panel_from_pdfc>;
+ bus-width = <18>;
+ };
+ };
+ };
+ };
};
diff --git a/Documentation/devicetree/bindings/soc/microchip/microchip,mpfs-irqmux.yaml b/Documentation/devicetree/bindings/soc/microchip/microchip,mpfs-irqmux.yaml
new file mode 100644
index 000000000000..51164772724f
--- /dev/null
+++ b/Documentation/devicetree/bindings/soc/microchip/microchip,mpfs-irqmux.yaml
@@ -0,0 +1,103 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/soc/microchip/microchip,mpfs-irqmux.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Microchip Polarfire SoC GPIO Interrupt Mux
+
+maintainers:
+ - Conor Dooley <conor.dooley@microchip.com>
+
+description: |
+ There are 3 GPIO controllers on this SoC, of which:
+ - GPIO controller 0 has 14 GPIOs
+ - GPIO controller 1 has 24 GPIOs
+ - GPIO controller 2 has 32 GPIOs
+
+ All GPIOs are capable of generating interrupts, for a total of 70.
+ There are only 41 IRQs available however, so a configurable mux is used to
+ ensure all GPIOs can be used for interrupt generation.
+ 38 of the 41 interrupts are in what the documentation calls "direct mode",
+ as they provide an exclusive connection from a GPIO to the PLIC.
+ Lines 18 to 23 on GPIO controller 1 are always in "direct mode".
+ The 3 remaining interrupts are used to mux the interrupts which do not have
+ a exclusive connection, one for each GPIO controller.
+
+properties:
+ compatible:
+ const: microchip,mpfs-irqmux
+
+ reg:
+ maxItems: 1
+
+ "#address-cells":
+ const: 0
+
+ "#interrupt-cells":
+ const: 1
+
+ interrupt-map-mask:
+ items:
+ - const: 0x7f
+
+ interrupt-map:
+ description: |
+ Specifies the mapping from GPIO interrupt lines to plic interrupts.
+
+ The child interrupt number set in arrays items is computed using the
+ following formula:
+ gpio_bank * 32 + gpio_number
+ with:
+ - gpio_bank: The GPIO bank number
+ - 0 for GPIO0,
+ - 1 for GPIO1,
+ - 2 for GPIO2
+ - gpio_number: Number of the gpio in the bank (0..31)
+ maxItems: 70
+
+required:
+ - compatible
+ - reg
+ - "#address-cells"
+ - "#interrupt-cells"
+ - interrupt-map-mask
+ - interrupt-map
+
+additionalProperties: false
+
+examples:
+ - |
+ interrupt-controller@54 {
+ compatible = "microchip,mpfs-irqmux";
+ reg = <0x54 0x4>;
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0x7f>;
+ interrupt-map = <0 &plic 13>, <1 &plic 14>, <2 &plic 15>,
+ <3 &plic 16>, <4 &plic 17>, <5 &plic 18>,
+ <6 &plic 19>, <7 &plic 20>, <8 &plic 21>,
+ <9 &plic 22>, <10 &plic 23>, <11 &plic 24>,
+ <12 &plic 25>, <13 &plic 26>,
+
+ <32 &plic 27>, <33 &plic 28>, <34 &plic 29>,
+ <35 &plic 30>, <36 &plic 31>, <37 &plic 32>,
+ <38 &plic 33>, <39 &plic 34>, <40 &plic 35>,
+ <41 &plic 36>, <42 &plic 37>, <43 &plic 38>,
+ <44 &plic 39>, <45 &plic 40>, <46 &plic 41>,
+ <47 &plic 42>, <48 &plic 43>, <49 &plic 44>,
+ <50 &plic 45>, <51 &plic 46>, <52 &plic 47>,
+ <53 &plic 48>, <54 &plic 49>, <55 &plic 50>,
+
+ <64 &plic 53>, <65 &plic 53>, <66 &plic 53>,
+ <67 &plic 53>, <68 &plic 53>, <69 &plic 53>,
+ <70 &plic 53>, <71 &plic 53>, <72 &plic 53>,
+ <73 &plic 53>, <74 &plic 53>, <75 &plic 53>,
+ <76 &plic 53>, <77 &plic 53>, <78 &plic 53>,
+ <79 &plic 53>, <80 &plic 53>, <81 &plic 53>,
+ <82 &plic 53>, <83 &plic 53>, <84 &plic 53>,
+ <85 &plic 53>, <86 &plic 53>, <87 &plic 53>,
+ <88 &plic 53>, <89 &plic 53>, <90 &plic 53>,
+ <91 &plic 53>, <92 &plic 53>, <93 &plic 53>,
+ <94 &plic 53>, <95 &plic 53>;
+ };
diff --git a/Documentation/devicetree/bindings/soc/microchip/microchip,mpfs-mss-top-sysreg.yaml b/Documentation/devicetree/bindings/soc/microchip/microchip,mpfs-mss-top-sysreg.yaml
index 44e4a50c3155..1e3725335b2c 100644
--- a/Documentation/devicetree/bindings/soc/microchip/microchip,mpfs-mss-top-sysreg.yaml
+++ b/Documentation/devicetree/bindings/soc/microchip/microchip,mpfs-mss-top-sysreg.yaml
@@ -15,10 +15,16 @@ description:
properties:
compatible:
- items:
- - const: microchip,mpfs-mss-top-sysreg
- - const: syscon
- - const: simple-mfd
+ oneOf:
+ - items:
+ - const: microchip,mpfs-mss-top-sysreg
+ - const: syscon
+ - const: simple-mfd
+ - items:
+ - const: microchip,pic64gx-mss-top-sysreg
+ - const: microchip,mpfs-mss-top-sysreg
+ - const: syscon
+ - const: simple-mfd
reg:
maxItems: 1
@@ -38,6 +44,10 @@ properties:
of PolarFire clock/reset IDs.
const: 1
+ interrupt-controller@54:
+ type: object
+ $ref: /schemas/soc/microchip/microchip,mpfs-irqmux.yaml
+
pinctrl@200:
type: object
$ref: /schemas/pinctrl/microchip,mpfs-pinctrl-iomux0.yaml
diff --git a/Documentation/devicetree/bindings/soc/microchip/microchip,mpfs-sys-controller.yaml b/Documentation/devicetree/bindings/soc/microchip/microchip,mpfs-sys-controller.yaml
index a3fa04f3a1bd..6cebc19db4f5 100644
--- a/Documentation/devicetree/bindings/soc/microchip/microchip,mpfs-sys-controller.yaml
+++ b/Documentation/devicetree/bindings/soc/microchip/microchip,mpfs-sys-controller.yaml
@@ -24,7 +24,9 @@ properties:
maxItems: 1
compatible:
- const: microchip,mpfs-sys-controller
+ enum:
+ - microchip,mpfs-sys-controller
+ - microchip,pic64gx-sys-controller
microchip,bitstream-flash:
$ref: /schemas/types.yaml#/definitions/phandle
diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,pmic-glink.yaml b/Documentation/devicetree/bindings/soc/qcom/qcom,pmic-glink.yaml
index 7085bf88afab..ff01d2f3ee5b 100644
--- a/Documentation/devicetree/bindings/soc/qcom/qcom,pmic-glink.yaml
+++ b/Documentation/devicetree/bindings/soc/qcom/qcom,pmic-glink.yaml
@@ -23,6 +23,8 @@ properties:
oneOf:
- items:
- enum:
+ - qcom,glymur-pmic-glink
+ - qcom,kaanapali-pmic-glink
- qcom,qcm6490-pmic-glink
- qcom,sc8180x-pmic-glink
- qcom,sc8280xp-pmic-glink
diff --git a/Documentation/devicetree/bindings/soc/renesas/renesas,rzg2l-sysc.yaml b/Documentation/devicetree/bindings/soc/renesas/renesas,rzg2l-sysc.yaml
index 4386b2c3fa4d..94ae72eb8fb6 100644
--- a/Documentation/devicetree/bindings/soc/renesas/renesas,rzg2l-sysc.yaml
+++ b/Documentation/devicetree/bindings/soc/renesas/renesas,rzg2l-sysc.yaml
@@ -24,6 +24,7 @@ properties:
- renesas,r9a07g044-sysc # RZ/G2{L,LC}
- renesas,r9a07g054-sysc # RZ/V2L
- renesas,r9a08g045-sysc # RZ/G3S
+ - renesas,r9a08g046-sysc # RZ/G3L
reg:
maxItems: 1
diff --git a/Documentation/devicetree/bindings/soc/renesas/renesas.yaml b/Documentation/devicetree/bindings/soc/renesas/renesas.yaml
index f4947ac65460..5c22c51b1533 100644
--- a/Documentation/devicetree/bindings/soc/renesas/renesas.yaml
+++ b/Documentation/devicetree/bindings/soc/renesas/renesas.yaml
@@ -548,6 +548,19 @@ properties:
- const: renesas,r9a08g045s33 # PCIe support
- const: renesas,r9a08g045
+ - description: RZ/G3L (R9A08G046)
+ items:
+ - enum:
+ - renesas,smarc2-evk # RZ SMARC Carrier-II EVK
+ - enum:
+ - renesas,rzg3l-smarcm # RZ/G3L SMARC Module (SoM)
+ - enum:
+ - renesas,r9a08g046l26 # Dual Cortex-A55 + Cortex-M33 + GE3D/VCP (14mm LFBGA)
+ - renesas,r9a08g046l28 # Dual Cortex-A55 + Cortex-M33 + GE3D/VCP (17mm LFBGA)
+ - renesas,r9a08g046l46 # Quad Cortex-A55 + Cortex-M33 + GE3D/VCP (14mm LFBGA)
+ - renesas,r9a08g046l48 # Quad Cortex-A55 + Cortex-M33 + GE3D/VCP (17mm LFBGA)
+ - const: renesas,r9a08g046
+
- description: RZ/V2M (R9A09G011)
items:
- enum:
diff --git a/Documentation/driver-api/reset.rst b/Documentation/driver-api/reset.rst
index f773100daaa4..7a6571849664 100644
--- a/Documentation/driver-api/reset.rst
+++ b/Documentation/driver-api/reset.rst
@@ -198,7 +198,6 @@ query the reset line status using reset_control_status().
reset_control_rearm
reset_control_put
of_reset_control_get_count
- of_reset_control_array_get
devm_reset_control_array_get
reset_control_get_count
diff --git a/MAINTAINERS b/MAINTAINERS
index ea12aaf625a7..d41dc26280b1 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2803,8 +2803,7 @@ S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/frank.li/linux.git
F: Documentation/devicetree/bindings/firmware/fsl*
F: Documentation/devicetree/bindings/firmware/nxp*
-F: arch/arm/boot/dts/nxp/imx/
-F: arch/arm/boot/dts/nxp/mxs/
+F: arch/arm/boot/dts/nxp/
F: arch/arm64/boot/dts/freescale/
X: Documentation/devicetree/bindings/media/i2c/
X: arch/arm64/boot/dts/freescale/fsl-*
@@ -8678,7 +8677,7 @@ F: drivers/phy/mediatek/phy-mtk-hdmi*
F: drivers/phy/mediatek/phy-mtk-mipi*
DRM DRIVERS FOR NVIDIA TEGRA
-M: Thierry Reding <thierry.reding@gmail.com>
+M: Thierry Reding <thierry.reding@kernel.org>
M: Mikko Perttunen <mperttunen@nvidia.com>
L: dri-devel@lists.freedesktop.org
L: linux-tegra@vger.kernel.org
@@ -20382,7 +20381,7 @@ S: Maintained
F: drivers/pci/controller/*mvebu*
PCI DRIVER FOR NVIDIA TEGRA
-M: Thierry Reding <thierry.reding@gmail.com>
+M: Thierry Reding <thierry.reding@kernel.org>
L: linux-tegra@vger.kernel.org
L: linux-pci@vger.kernel.org
S: Supported
@@ -22902,7 +22901,7 @@ F: Documentation/devicetree/bindings/pinctrl/microchip,mpfs-pinctrl-mssio.yaml
F: Documentation/devicetree/bindings/pinctrl/microchip,pic64gx-pinctrl-gpio2.yaml
F: Documentation/devicetree/bindings/pwm/microchip,corepwm.yaml
F: Documentation/devicetree/bindings/riscv/microchip.yaml
-F: Documentation/devicetree/bindings/soc/microchip/microchip,mpfs-sys-controller.yaml
+F: Documentation/devicetree/bindings/soc/microchip/microchip,mpfs*.yaml
F: Documentation/devicetree/bindings/spi/microchip,mpfs-spi.yaml
F: Documentation/devicetree/bindings/usb/microchip,mpfs-musb.yaml
F: arch/riscv/boot/dts/microchip/
@@ -25210,6 +25209,7 @@ F: drivers/hwmon/pmbus/stef48h28.c
ST STM32 FIREWALL
M: Gatien Chevallier <gatien.chevallier@foss.st.com>
S: Maintained
+F: drivers/bus/stm32_dbg_bus.c
F: drivers/bus/stm32_etzpc.c
F: drivers/bus/stm32_firewall.c
F: drivers/bus/stm32_rifsc.c
@@ -26144,7 +26144,7 @@ F: include/linux/tee_drv.h
F: include/uapi/linux/tee.h
TEGRA ARCHITECTURE SUPPORT
-M: Thierry Reding <thierry.reding@gmail.com>
+M: Thierry Reding <thierry.reding@kernel.org>
M: Jonathan Hunter <jonathanh@nvidia.com>
L: linux-tegra@vger.kernel.org
S: Supported
@@ -26176,7 +26176,7 @@ S: Supported
F: drivers/i2c/busses/i2c-tegra.c
TEGRA IOMMU DRIVERS
-M: Thierry Reding <thierry.reding@gmail.com>
+M: Thierry Reding <thierry.reding@kernel.org>
R: Krishna Reddy <vdumpa@nvidia.com>
L: linux-tegra@vger.kernel.org
S: Supported
@@ -26197,12 +26197,12 @@ F: Documentation/devicetree/bindings/mtd/nvidia,tegra20-nand.yaml
F: drivers/mtd/nand/raw/tegra_nand.c
TEGRA PWM DRIVER
-M: Thierry Reding <thierry.reding@gmail.com>
+M: Thierry Reding <thierry.reding@kernel.org>
S: Supported
F: drivers/pwm/pwm-tegra.c
TEGRA QUAD SPI DRIVER
-M: Thierry Reding <thierry.reding@gmail.com>
+M: Thierry Reding <thierry.reding@kernel.org>
M: Jonathan Hunter <jonathanh@nvidia.com>
M: Sowjanya Komatineni <skomatineni@nvidia.com>
L: linux-tegra@vger.kernel.org
@@ -26220,7 +26220,7 @@ S: Supported
F: drivers/spi/spi-tegra*
TEGRA VIDEO DRIVER
-M: Thierry Reding <thierry.reding@gmail.com>
+M: Thierry Reding <thierry.reding@kernel.org>
M: Jonathan Hunter <jonathanh@nvidia.com>
M: Sowjanya Komatineni <skomatineni@nvidia.com>
M: Luca Ceresoli <luca.ceresoli@bootlin.com>
diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig
index 2a1b46f07080..7a1b04007efb 100644
--- a/drivers/bus/Kconfig
+++ b/drivers/bus/Kconfig
@@ -169,6 +169,16 @@ config QCOM_SSC_BLOCK_BUS
i2c/spi/uart controllers, a hexagon core, and a clock controller
which provides clocks for the above.
+config STM32_DBG_BUS
+ tristate "OP-TEE based debug access bus"
+ depends on OPTEE && STM32_FIREWALL
+ depends on ARCH_STM32 || COMPILE_TEST
+ help
+ Select this to get the support for the OP-TEE based STM32 debug bus
+ driver that is used to handle debug-related peripherals on STM32
+ platforms when the debug configuration is not accessible by the
+ normal world.
+
config STM32_FIREWALL
bool "STM32 Firewall framework"
depends on (ARCH_STM32 || COMPILE_TEST) && OF
diff --git a/drivers/bus/Makefile b/drivers/bus/Makefile
index 8e693fe8a03a..799724cfc2df 100644
--- a/drivers/bus/Makefile
+++ b/drivers/bus/Makefile
@@ -27,6 +27,7 @@ obj-$(CONFIG_OMAP_INTERCONNECT) += omap_l3_smx.o omap_l3_noc.o
obj-$(CONFIG_OMAP_OCP2SCP) += omap-ocp2scp.o
obj-$(CONFIG_QCOM_EBI2) += qcom-ebi2.o
obj-$(CONFIG_QCOM_SSC_BLOCK_BUS) += qcom-ssc-block-bus.o
+obj-$(CONFIG_STM32_DBG_BUS) += stm32_dbg_bus.o
obj-$(CONFIG_STM32_FIREWALL) += stm32_firewall.o stm32_rifsc.o stm32_etzpc.o
obj-$(CONFIG_SUN50I_DE2_BUS) += sun50i-de2.o
obj-$(CONFIG_SUNXI_RSB) += sunxi-rsb.o
diff --git a/drivers/bus/imx-aipstz.c b/drivers/bus/imx-aipstz.c
index 5fdf377f5d06..83371e5b35a2 100644
--- a/drivers/bus/imx-aipstz.c
+++ b/drivers/bus/imx-aipstz.c
@@ -11,9 +11,19 @@
#include <linux/regmap.h>
#define IMX_AIPSTZ_MPR0 0x0
+#define IMX_AIPSTZ_OPACR0 0x40
+#define IMX_AIPSTZ_OPACR1 0x44
+#define IMX_AIPSTZ_OPACR2 0x48
+#define IMX_AIPSTZ_OPACR3 0x4c
+#define IMX_AIPSTZ_OPACR4 0x50
struct imx_aipstz_config {
u32 mpr0;
+ u32 opacr0;
+ u32 opacr1;
+ u32 opacr2;
+ u32 opacr3;
+ u32 opacr4;
};
struct imx_aipstz_data {
@@ -24,6 +34,11 @@ struct imx_aipstz_data {
static void imx_aipstz_apply_default(struct imx_aipstz_data *data)
{
writel(data->default_cfg->mpr0, data->base + IMX_AIPSTZ_MPR0);
+ writel(data->default_cfg->opacr0, data->base + IMX_AIPSTZ_OPACR0);
+ writel(data->default_cfg->opacr1, data->base + IMX_AIPSTZ_OPACR1);
+ writel(data->default_cfg->opacr2, data->base + IMX_AIPSTZ_OPACR2);
+ writel(data->default_cfg->opacr3, data->base + IMX_AIPSTZ_OPACR3);
+ writel(data->default_cfg->opacr4, data->base + IMX_AIPSTZ_OPACR4);
}
static const struct of_device_id imx_aipstz_match_table[] = {
diff --git a/drivers/bus/stm32_dbg_bus.c b/drivers/bus/stm32_dbg_bus.c
new file mode 100644
index 000000000000..e30ef3465609
--- /dev/null
+++ b/drivers/bus/stm32_dbg_bus.c
@@ -0,0 +1,250 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2026, STMicroelectronics - All Rights Reserved
+ */
+
+#include <linux/bus/stm32_firewall.h>
+#include <linux/bus/stm32_firewall_device.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/tee_drv.h>
+#include <linux/types.h>
+
+enum stm32_dbg_profile {
+ PERIPHERAL_DBG_PROFILE = 0,
+ HDP_DBG_PROFILE = 1,
+};
+
+enum stm32_dbg_pta_command {
+ /*
+ * PTA_CMD_GRANT_DBG_ACCESS - Verify the debug configuration against the given debug profile
+ * and grant access or not
+ *
+ * [in] value[0].a Debug profile to grant access to.
+ */
+ PTA_CMD_GRANT_DBG_ACCESS,
+};
+
+/**
+ * struct stm32_dbg_bus - OP-TEE based STM32 debug bus private data
+ * @dev: STM32 debug bus device.
+ * @ctx: OP-TEE context handler.
+ */
+struct stm32_dbg_bus {
+ struct device *dev;
+ struct tee_context *ctx;
+};
+
+/* Expect at most 1 instance of this driver */
+static struct stm32_dbg_bus *stm32_dbg_bus_priv;
+
+static int stm32_dbg_pta_open_session(u32 *id)
+{
+ struct tee_client_device *dbg_bus_dev = to_tee_client_device(stm32_dbg_bus_priv->dev);
+ struct tee_ioctl_open_session_arg sess_arg;
+ int ret;
+
+ memset(&sess_arg, 0, sizeof(sess_arg));
+ export_uuid(sess_arg.uuid, &dbg_bus_dev->id.uuid);
+ sess_arg.clnt_login = TEE_IOCTL_LOGIN_REE_KERNEL;
+
+ ret = tee_client_open_session(stm32_dbg_bus_priv->ctx, &sess_arg, NULL);
+ if (ret < 0 || sess_arg.ret) {
+ dev_err(stm32_dbg_bus_priv->dev, "Failed opening tee session, err: %#x\n",
+ sess_arg.ret);
+ return -EOPNOTSUPP;
+ }
+
+ *id = sess_arg.session;
+
+ return 0;
+}
+
+static void stm32_dbg_pta_close_session(u32 id)
+{
+ tee_client_close_session(stm32_dbg_bus_priv->ctx, id);
+}
+
+static int stm32_dbg_bus_grant_access(struct stm32_firewall_controller *ctrl, u32 dbg_profile)
+{
+ struct tee_ioctl_invoke_arg inv_arg = {0};
+ struct tee_param param[1] = {0};
+ u32 session_id;
+ int ret;
+
+ if (dbg_profile != PERIPHERAL_DBG_PROFILE && dbg_profile != HDP_DBG_PROFILE)
+ return -EOPNOTSUPP;
+
+ ret = stm32_dbg_pta_open_session(&session_id);
+ if (ret)
+ return ret;
+
+ inv_arg.func = PTA_CMD_GRANT_DBG_ACCESS;
+ inv_arg.session = session_id;
+ inv_arg.num_params = 1;
+ param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT;
+ param[0].u.value.a = dbg_profile;
+
+ ret = tee_client_invoke_func(stm32_dbg_bus_priv->ctx, &inv_arg, param);
+ if (ret < 0 || inv_arg.ret != 0) {
+ dev_dbg(stm32_dbg_bus_priv->dev,
+ "When invoking function, err %x, TEE returns: %x\n", ret, inv_arg.ret);
+ if (!ret)
+ ret = -EACCES;
+ }
+
+ stm32_dbg_pta_close_session(session_id);
+
+ return ret;
+}
+
+/* Implement mandatory release_access ops even if it does nothing*/
+static void stm32_dbg_bus_release_access(struct stm32_firewall_controller *ctrl, u32 dbg_profile)
+{
+}
+
+static int stm32_dbg_bus_plat_probe(struct platform_device *pdev)
+{
+ struct stm32_firewall_controller *dbg_controller;
+ int ret;
+
+ /* Defer if OP-TEE service is not yet available */
+ if (!stm32_dbg_bus_priv)
+ return -EPROBE_DEFER;
+
+ dbg_controller = devm_kzalloc(&pdev->dev, sizeof(*dbg_controller), GFP_KERNEL);
+ if (!dbg_controller)
+ return dev_err_probe(&pdev->dev, -ENOMEM, "Couldn't allocate debug controller\n");
+
+ dbg_controller->dev = &pdev->dev;
+ dbg_controller->mmio = NULL;
+ dbg_controller->name = dev_driver_string(dbg_controller->dev);
+ dbg_controller->type = STM32_PERIPHERAL_FIREWALL;
+ dbg_controller->grant_access = stm32_dbg_bus_grant_access;
+ dbg_controller->release_access = stm32_dbg_bus_release_access;
+
+ ret = stm32_firewall_controller_register(dbg_controller);
+ if (ret) {
+ dev_err(dbg_controller->dev, "Couldn't register as a firewall controller: %d", ret);
+ return ret;
+ }
+
+ ret = stm32_firewall_populate_bus(dbg_controller);
+ if (ret) {
+ dev_err(dbg_controller->dev, "Couldn't populate debug bus: %d", ret);
+ stm32_firewall_controller_unregister(dbg_controller);
+ return ret;
+ }
+
+ pm_runtime_enable(&pdev->dev);
+
+ ret = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
+ if (ret) {
+ dev_err(dbg_controller->dev, "Couldn't populate the node: %d", ret);
+ stm32_firewall_controller_unregister(dbg_controller);
+ return ret;
+ }
+
+ return 0;
+}
+
+static const struct of_device_id stm32_dbg_bus_of_match[] = {
+ { .compatible = "st,stm32mp131-dbg-bus", },
+ { .compatible = "st,stm32mp151-dbg-bus", },
+ { },
+};
+MODULE_DEVICE_TABLE(of, stm32_dbg_bus_of_match);
+
+static struct platform_driver stm32_dbg_bus_driver = {
+ .probe = stm32_dbg_bus_plat_probe,
+ .driver = {
+ .name = "stm32-dbg-bus",
+ .of_match_table = stm32_dbg_bus_of_match,
+ },
+};
+
+static int optee_ctx_match(struct tee_ioctl_version_data *ver, const void *data)
+{
+ return (ver->impl_id == TEE_IMPL_ID_OPTEE);
+}
+
+static void stm32_dbg_bus_remove(struct tee_client_device *tee_dev)
+{
+ tee_client_close_context(stm32_dbg_bus_priv->ctx);
+ stm32_dbg_bus_priv = NULL;
+
+ of_platform_depopulate(&tee_dev->dev);
+}
+
+static int stm32_dbg_bus_probe(struct tee_client_device *tee_dev)
+{
+ struct device *dev = &tee_dev->dev;
+ struct stm32_dbg_bus *priv;
+ int ret = 0;
+
+ if (stm32_dbg_bus_priv)
+ return dev_err_probe(dev, -EBUSY,
+ "A STM32 debug bus device is already initialized\n");
+
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ /* Open context with TEE driver */
+ priv->ctx = tee_client_open_context(NULL, optee_ctx_match, NULL, NULL);
+ if (IS_ERR_OR_NULL(priv->ctx))
+ return dev_err_probe(dev, PTR_ERR_OR_ZERO(priv->ctx), "Cannot open TEE context\n");
+
+ stm32_dbg_bus_priv = priv;
+ stm32_dbg_bus_priv->dev = dev;
+
+ return ret;
+}
+
+static const struct tee_client_device_id optee_dbg_bus_id_table[] = {
+ {UUID_INIT(0xdd05bc8b, 0x9f3b, 0x49f0,
+ 0xb6, 0x49, 0x01, 0xaa, 0x10, 0xc1, 0xc2, 0x10)},
+ {}
+};
+
+static struct tee_client_driver stm32_optee_dbg_bus_driver = {
+ .id_table = optee_dbg_bus_id_table,
+ .probe = stm32_dbg_bus_probe,
+ .remove = stm32_dbg_bus_remove,
+ .driver = {
+ .name = "optee_dbg_bus",
+ },
+};
+
+static void __exit stm32_optee_dbg_bus_driver_exit(void)
+{
+ platform_driver_unregister(&stm32_dbg_bus_driver);
+ tee_client_driver_unregister(&stm32_optee_dbg_bus_driver);
+}
+module_exit(stm32_optee_dbg_bus_driver_exit);
+
+static int __init stm32_optee_dbg_bus_driver_init(void)
+{
+ int err;
+
+ err = tee_client_driver_register(&stm32_optee_dbg_bus_driver);
+ if (err)
+ return err;
+
+ err = platform_driver_register(&stm32_dbg_bus_driver);
+ if (err)
+ tee_client_driver_unregister(&stm32_optee_dbg_bus_driver);
+
+ return err;
+}
+module_init(stm32_optee_dbg_bus_driver_init);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Gatien Chevallier <gatien.chevallier@foss.st.com>");
+MODULE_DESCRIPTION("OP-TEE based STM32 debug access bus driver");
diff --git a/drivers/bus/stm32_etzpc.c b/drivers/bus/stm32_etzpc.c
index 7fc0f16960be..4918a14e507e 100644
--- a/drivers/bus/stm32_etzpc.c
+++ b/drivers/bus/stm32_etzpc.c
@@ -5,6 +5,7 @@
#include <linux/bitfield.h>
#include <linux/bits.h>
+#include <linux/bus/stm32_firewall.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/init.h>
@@ -16,8 +17,6 @@
#include <linux/platform_device.h>
#include <linux/types.h>
-#include "stm32_firewall.h"
-
/*
* ETZPC registers
*/
diff --git a/drivers/bus/stm32_firewall.c b/drivers/bus/stm32_firewall.c
index 7e7afe8007db..e3619dba8b06 100644
--- a/drivers/bus/stm32_firewall.c
+++ b/drivers/bus/stm32_firewall.c
@@ -5,6 +5,7 @@
#include <linux/bitfield.h>
#include <linux/bits.h>
+#include <linux/bus/stm32_firewall.h>
#include <linux/bus/stm32_firewall_device.h>
#include <linux/device.h>
#include <linux/err.h>
@@ -18,8 +19,6 @@
#include <linux/types.h>
#include <linux/slab.h>
-#include "stm32_firewall.h"
-
/* Corresponds to STM32_FIREWALL_MAX_EXTRA_ARGS + firewall ID */
#define STM32_FIREWALL_MAX_ARGS (STM32_FIREWALL_MAX_EXTRA_ARGS + 1)
@@ -185,6 +184,48 @@ void stm32_firewall_release_access_by_id(struct stm32_firewall *firewall, u32 su
}
EXPORT_SYMBOL_GPL(stm32_firewall_release_access_by_id);
+int stm32_firewall_get_grant_all_access(struct device *dev, struct stm32_firewall **firewall,
+ int *nb_firewall)
+{
+ struct stm32_firewall *loc_firewall;
+ int err;
+ int i;
+
+ *nb_firewall = of_count_phandle_with_args(dev->of_node, "access-controllers",
+ "#access-controller-cells");
+ if (*nb_firewall < 0)
+ return *nb_firewall;
+
+ if (!*nb_firewall) {
+ *firewall = NULL;
+ return 0;
+ }
+
+ loc_firewall = devm_kcalloc(dev, *nb_firewall, sizeof(*loc_firewall), GFP_KERNEL);
+ if (!loc_firewall)
+ return -ENOMEM;
+
+ /* Get stm32 firewall information */
+ err = stm32_firewall_get_firewall(dev->of_node, loc_firewall, *nb_firewall);
+ if (err)
+ return err;
+
+ for (i = 0; i < *nb_firewall; i++) {
+ err = stm32_firewall_grant_access(&loc_firewall[i]);
+ if (err) {
+ while (i--)
+ stm32_firewall_release_access(&loc_firewall[i]);
+
+ return err;
+ }
+ }
+
+ *firewall = loc_firewall;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(stm32_firewall_get_grant_all_access);
+
/* Firewall controller API */
int stm32_firewall_controller_register(struct stm32_firewall_controller *firewall_controller)
@@ -241,7 +282,6 @@ EXPORT_SYMBOL_GPL(stm32_firewall_controller_unregister);
int stm32_firewall_populate_bus(struct stm32_firewall_controller *firewall_controller)
{
struct stm32_firewall *firewalls;
- struct device_node *child;
struct device *parent;
unsigned int i;
int len;
@@ -251,30 +291,25 @@ int stm32_firewall_populate_bus(struct stm32_firewall_controller *firewall_contr
dev_dbg(parent, "Populating %s system bus\n", dev_name(firewall_controller->dev));
- for_each_available_child_of_node(dev_of_node(parent), child) {
+ for_each_available_child_of_node_scoped(dev_of_node(parent), child) {
/* The access-controllers property is mandatory for firewall bus devices */
len = of_count_phandle_with_args(child, "access-controllers",
"#access-controller-cells");
- if (len <= 0) {
- of_node_put(child);
+ if (len <= 0)
return -EINVAL;
- }
firewalls = kzalloc_objs(*firewalls, len);
- if (!firewalls) {
- of_node_put(child);
+ if (!firewalls)
return -ENOMEM;
- }
err = stm32_firewall_get_firewall(child, firewalls, (unsigned int)len);
if (err) {
kfree(firewalls);
- of_node_put(child);
return err;
}
for (i = 0; i < len; i++) {
- if (firewall_controller->grant_access(firewall_controller,
+ if (firewall_controller->grant_access(firewalls[i].firewall_ctrl,
firewalls[i].firewall_id)) {
/*
* Peripheral access not allowed or not defined.
diff --git a/drivers/bus/stm32_rifsc.c b/drivers/bus/stm32_rifsc.c
index debeaf8ea1bd..19d10379dcef 100644
--- a/drivers/bus/stm32_rifsc.c
+++ b/drivers/bus/stm32_rifsc.c
@@ -5,6 +5,7 @@
#include <linux/bitfield.h>
#include <linux/bits.h>
+#include <linux/bus/stm32_firewall.h>
#include <linux/debugfs.h>
#include <linux/device.h>
#include <linux/err.h>
@@ -15,10 +16,9 @@
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
+#include <linux/string.h>
#include <linux/types.h>
-#include "stm32_firewall.h"
-
/*
* RIFSC offset register
*/
@@ -450,7 +450,7 @@ static void stm32_rifsc_fill_rimu_dbg_entry(struct rifsc_dbg_private *rifsc,
const struct stm32_rifsc_resources_names *dbg_names = rifsc->res_names;
u32 rimc_attr = readl_relaxed(rifsc->mmio + RIFSC_RIMC_ATTR0 + 0x4 * i);
- snprintf(dbg_entry->m_name, sizeof(dbg_entry->m_name), "%s", dbg_names->initiator_names[i]);
+ strscpy(dbg_entry->m_name, dbg_names->initiator_names[i]);
dbg_entry->m_cid = FIELD_GET(RIFSC_RIMC_MCID_MASK, rimc_attr);
dbg_entry->cidsel = rimc_attr & RIFSC_RIMC_CIDSEL;
dbg_entry->m_sec = rimc_attr & RIFSC_RIMC_MSEC;
@@ -469,8 +469,7 @@ static void stm32_rifsc_fill_dev_dbg_entry(struct rifsc_dbg_private *rifsc,
sec_cfgr = readl_relaxed(rifsc->mmio + RIFSC_RISC_SECCFGR0 + 0x4 * reg_id);
priv_cfgr = readl_relaxed(rifsc->mmio + RIFSC_RISC_PRIVCFGR0 + 0x4 * reg_id);
- snprintf(dbg_entry->dev_name, sizeof(dbg_entry->dev_name), "%s",
- dbg_names->device_names[i]);
+ strscpy(dbg_entry->dev_name, dbg_names->device_names[i]);
dbg_entry->dev_id = i;
dbg_entry->dev_cid_filt_en = cid_cfgr & CIDCFGR_CFEN;
dbg_entry->dev_sem_en = cid_cfgr & CIDCFGR_SEMEN;
@@ -688,34 +687,6 @@ static int stm32_rifsc_grant_access(struct stm32_firewall_controller *ctrl, u32
sec_reg_value = readl(rifsc_controller->mmio + RIFSC_RISC_SECCFGR0 + 0x4 * reg_id);
cid_reg_value = readl(rifsc_controller->mmio + RIFSC_RISC_PER0_CIDCFGR + 0x8 * firewall_id);
- /* First check conditions for semaphore mode, which doesn't take into account static CID. */
- if ((cid_reg_value & CIDCFGR_SEMEN) && (cid_reg_value & CIDCFGR_CFEN)) {
- if (cid_reg_value & BIT(RIF_CID1 + SEMWL_SHIFT)) {
- /* Static CID is irrelevant if semaphore mode */
- goto skip_cid_check;
- } else {
- dev_dbg(rifsc_controller->dev,
- "Invalid bus semaphore configuration: index %d\n", firewall_id);
- return -EACCES;
- }
- }
-
- /*
- * Skip CID check if CID filtering isn't enabled or filtering is enabled on CID0, which
- * corresponds to whatever CID.
- */
- if (!(cid_reg_value & CIDCFGR_CFEN) ||
- FIELD_GET(RIFSC_RISC_SCID_MASK, cid_reg_value) == RIF_CID0)
- goto skip_cid_check;
-
- /* Coherency check with the CID configuration */
- if (FIELD_GET(RIFSC_RISC_SCID_MASK, cid_reg_value) != RIF_CID1) {
- dev_dbg(rifsc_controller->dev, "Invalid CID configuration for peripheral: %d\n",
- firewall_id);
- return -EACCES;
- }
-
-skip_cid_check:
/* Check security configuration */
if (sec_reg_value & BIT(reg_offset)) {
dev_dbg(rifsc_controller->dev,
@@ -723,19 +694,31 @@ skip_cid_check:
return -EACCES;
}
- /*
- * If the peripheral is in semaphore mode, take the semaphore so that
- * the CID1 has the ownership.
- */
- if ((cid_reg_value & CIDCFGR_SEMEN) && (cid_reg_value & CIDCFGR_CFEN)) {
+ /* Skip CID check if CID filtering isn't enabled */
+ if (!(cid_reg_value & CIDCFGR_CFEN))
+ goto skip_cid_check;
+
+ /* First check conditions for semaphore mode, which doesn't take into account static CID. */
+ if (cid_reg_value & CIDCFGR_SEMEN) {
+ if (!(cid_reg_value & BIT(RIF_CID1 + SEMWL_SHIFT))) {
+ dev_dbg(rifsc_controller->dev,
+ "Invalid bus semaphore configuration: index %d\n", firewall_id);
+ return -EACCES;
+ }
+
rc = stm32_rif_acquire_semaphore(rifsc_controller, firewall_id);
if (rc) {
- dev_err(rifsc_controller->dev,
+ dev_dbg(rifsc_controller->dev,
"Couldn't acquire semaphore for peripheral: %d\n", firewall_id);
return rc;
}
+ } else if (FIELD_GET(RIFSC_RISC_SCID_MASK, cid_reg_value) != RIF_CID1) {
+ dev_dbg(rifsc_controller->dev, "Invalid CID configuration for peripheral: %d\n",
+ firewall_id);
+ return -EACCES;
}
+skip_cid_check:
return 0;
}
diff --git a/drivers/clk/samsung/clk-acpm.c b/drivers/clk/samsung/clk-acpm.c
index b90809ce3f88..d8944160793a 100644
--- a/drivers/clk/samsung/clk-acpm.c
+++ b/drivers/clk/samsung/clk-acpm.c
@@ -20,7 +20,7 @@ struct acpm_clk {
u32 id;
struct clk_hw hw;
unsigned int mbox_chan_id;
- const struct acpm_handle *handle;
+ struct acpm_handle *handle;
};
struct acpm_clk_variant {
@@ -113,7 +113,7 @@ static int acpm_clk_register(struct device *dev, struct acpm_clk *aclk,
static int acpm_clk_probe(struct platform_device *pdev)
{
- const struct acpm_handle *acpm_handle;
+ struct acpm_handle *acpm_handle;
struct clk_hw_onecell_data *clk_data;
struct clk_hw **hws;
struct device *dev = &pdev->dev;
diff --git a/drivers/clk/spear/clk-vco-pll.c b/drivers/clk/spear/clk-vco-pll.c
index 601e123f5c4b..faba727e2f84 100644
--- a/drivers/clk/spear/clk-vco-pll.c
+++ b/drivers/clk/spear/clk-vco-pll.c
@@ -343,13 +343,15 @@ struct clk *clk_register_vco_pll(const char *vco_name, const char *pll_name,
tpll_clk = clk_register(NULL, &pll->hw);
if (IS_ERR_OR_NULL(tpll_clk))
- goto free_pll;
+ goto unregister_clk;
if (pll_clk)
*pll_clk = tpll_clk;
return vco_clk;
+unregister_clk:
+ clk_unregister(vco_clk);
free_pll:
kfree(pll);
free_vco:
diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
index f2f94d4d533e..eb2782848283 100644
--- a/drivers/firmware/arm_ffa/driver.c
+++ b/drivers/firmware/arm_ffa/driver.c
@@ -2078,7 +2078,7 @@ static int __init ffa_init(void)
ret = ffa_rxtx_map(virt_to_phys(drv_info->tx_buffer),
virt_to_phys(drv_info->rx_buffer),
- rxtx_bufsz / FFA_PAGE_SIZE);
+ PAGE_ALIGN(rxtx_bufsz) / FFA_PAGE_SIZE);
if (ret) {
pr_err("failed to register FFA RxTx buffers\n");
goto free_pages;
diff --git a/drivers/firmware/arm_scmi/base.c b/drivers/firmware/arm_scmi/base.c
index 22267bbd0f4d..cd1331c2fc40 100644
--- a/drivers/firmware/arm_scmi/base.c
+++ b/drivers/firmware/arm_scmi/base.c
@@ -7,6 +7,7 @@
#define pr_fmt(fmt) "SCMI Notifications BASE - " fmt
+#include <linux/math.h>
#include <linux/module.h>
#include <linux/scmi_protocol.h>
@@ -219,8 +220,7 @@ scmi_base_implementation_list_get(const struct scmi_protocol_handle *ph,
}
real_list_sz = t->rx.len - sizeof(u32);
- calc_list_sz = (1 + (loop_num_ret - 1) / sizeof(u32)) *
- sizeof(u32);
+ calc_list_sz = round_up(loop_num_ret, sizeof(u32));
if (calc_list_sz != real_list_sz) {
dev_warn(dev,
"Malformed reply - real_sz:%zd calc_sz:%u (loop_num_ret:%d)\n",
diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h
index 7c35c95fddba..7c9617d080a0 100644
--- a/drivers/firmware/arm_scmi/common.h
+++ b/drivers/firmware/arm_scmi/common.h
@@ -235,6 +235,9 @@ struct scmi_transport_ops {
* to have an execution latency lesser-equal to the threshold
* should be considered for atomic mode operation: such
* decision is finally left up to the SCMI drivers.
+ * @no_completion_irq: Flag to indicate that this transport has no completion
+ * interrupt and has to be polled. This is similar to the
+ * force_polling below, except this is set via DT property.
* @force_polling: Flag to force this whole transport to use SCMI core polling
* mechanism instead of completion interrupts even if available.
* @sync_cmds_completed_on_ret: Flag to indicate that the transport assures
@@ -254,6 +257,7 @@ struct scmi_desc {
int max_msg;
int max_msg_size;
unsigned int atomic_threshold;
+ bool no_completion_irq;
const bool force_polling;
const bool sync_cmds_completed_on_ret;
const bool atomic_enabled;
diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
index 3e76a3204ba4..f167194f7cf6 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -2735,6 +2735,7 @@ static int scmi_chan_setup(struct scmi_info *info, struct device_node *of_node,
cinfo->is_p2a = !tx;
cinfo->rx_timeout_ms = info->desc->max_rx_timeout_ms;
cinfo->max_msg_size = info->desc->max_msg_size;
+ cinfo->no_completion_irq = info->desc->no_completion_irq;
/* Create a unique name for this transport device */
snprintf(name, 32, "__scmi_transport_device_%s_%02X",
@@ -3150,6 +3151,9 @@ static const struct scmi_desc *scmi_transport_setup(struct device *dev)
if (ret && ret != -EINVAL)
dev_err(dev, "Malformed arm,max-msg DT property.\n");
+ trans->desc.no_completion_irq = of_property_read_bool(dev->of_node,
+ "arm,no-completion-irq");
+
dev_info(dev,
"SCMI max-rx-timeout: %dms / max-msg-size: %dbytes / max-msg: %d\n",
trans->desc.max_rx_timeout_ms, trans->desc.max_msg_size,
diff --git a/drivers/firmware/arm_scmi/quirks.h b/drivers/firmware/arm_scmi/quirks.h
index a71fde85a527..d8ba60b95652 100644
--- a/drivers/firmware/arm_scmi/quirks.h
+++ b/drivers/firmware/arm_scmi/quirks.h
@@ -20,10 +20,10 @@
* named as _qn.
*/
#define SCMI_QUIRK(_qn, _blk) \
- do { \
+ ({ \
if (static_branch_unlikely(&(scmi_quirk_ ## _qn))) \
(_blk); \
- } while (0)
+ })
void scmi_quirks_initialize(void);
void scmi_quirks_enable(struct device *dev, const char *vend,
@@ -34,10 +34,10 @@ void scmi_quirks_enable(struct device *dev, const char *vend,
#define DECLARE_SCMI_QUIRK(_qn)
/* Force quirks compilation even when SCMI Quirks are disabled */
#define SCMI_QUIRK(_qn, _blk) \
- do { \
+ ({ \
if (0) \
(_blk); \
- } while (0)
+ })
static inline void scmi_quirks_initialize(void) { }
static inline void scmi_quirks_enable(struct device *dev, const char *vend,
diff --git a/drivers/firmware/qcom/qcom_qseecom_uefisecapp.c b/drivers/firmware/qcom/qcom_qseecom_uefisecapp.c
index 98a463e9774b..befa68d1dcaf 100644
--- a/drivers/firmware/qcom/qcom_qseecom_uefisecapp.c
+++ b/drivers/firmware/qcom/qcom_qseecom_uefisecapp.c
@@ -699,20 +699,18 @@ static DEFINE_MUTEX(__qcuefi_lock);
static int qcuefi_set_reference(struct qcuefi_client *qcuefi)
{
- mutex_lock(&__qcuefi_lock);
+ guard(mutex)(&__qcuefi_lock);
- if (qcuefi && __qcuefi) {
- mutex_unlock(&__qcuefi_lock);
+ if (qcuefi && __qcuefi)
return -EEXIST;
- }
__qcuefi = qcuefi;
- mutex_unlock(&__qcuefi_lock);
return 0;
}
static struct qcuefi_client *qcuefi_acquire(void)
+ __acquires(__qcuefi_lock)
{
mutex_lock(&__qcuefi_lock);
if (!__qcuefi) {
@@ -723,6 +721,7 @@ static struct qcuefi_client *qcuefi_acquire(void)
}
static void qcuefi_release(void)
+ __releases(__qcuefi_lock)
{
mutex_unlock(&__qcuefi_lock);
}
diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
index 8fbc96693a55..9b06a69d3a6d 100644
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -199,19 +199,18 @@ static int qcom_scm_bw_enable(void)
if (!__scm->path)
return 0;
- mutex_lock(&__scm->scm_bw_lock);
+ guard(mutex)(&__scm->scm_bw_lock);
+
if (!__scm->scm_vote_count) {
ret = icc_set_bw(__scm->path, 0, UINT_MAX);
if (ret < 0) {
dev_err(__scm->dev, "failed to set bandwidth request\n");
- goto err_bw;
+ return ret;
}
}
__scm->scm_vote_count++;
-err_bw:
- mutex_unlock(&__scm->scm_bw_lock);
- return ret;
+ return 0;
}
static void qcom_scm_bw_disable(void)
@@ -923,14 +922,13 @@ struct resource_table *qcom_scm_pas_get_rsc_table(struct qcom_scm_pas_context *c
goto free_input_rt;
}
- tbl_ptr = kzalloc(size, GFP_KERNEL);
+ tbl_ptr = kmemdup(output_rt_tzm, size, GFP_KERNEL);
if (!tbl_ptr) {
qcom_tzmem_free(output_rt_tzm);
ret = -ENOMEM;
goto free_input_rt;
}
- memcpy(tbl_ptr, output_rt_tzm, size);
*output_rt_size = size;
qcom_tzmem_free(output_rt_tzm);
@@ -2290,15 +2288,18 @@ EXPORT_SYMBOL_GPL(qcom_scm_qseecom_app_send);
*/
static const struct of_device_id qcom_scm_qseecom_allowlist[] __maybe_unused = {
{ .compatible = "asus,vivobook-s15" },
+ { .compatible = "asus,vivobook-s15-x1p4" },
{ .compatible = "asus,zenbook-a14-ux3407qa" },
{ .compatible = "asus,zenbook-a14-ux3407ra" },
{ .compatible = "dell,inspiron-14-plus-7441" },
{ .compatible = "dell,latitude-7455" },
{ .compatible = "dell,xps13-9345" },
+ { .compatible = "ecs,liva-qc710" },
{ .compatible = "hp,elitebook-ultra-g1q" },
{ .compatible = "hp,omnibook-x14" },
{ .compatible = "huawei,gaokun3" },
{ .compatible = "lenovo,flex-5g" },
+ { .compatible = "lenovo,ideacentre-mini-01q8x10" },
{ .compatible = "lenovo,thinkbook-16" },
{ .compatible = "lenovo,thinkpad-t14s" },
{ .compatible = "lenovo,thinkpad-x13s", },
@@ -2309,7 +2310,10 @@ static const struct of_device_id qcom_scm_qseecom_allowlist[] __maybe_unused = {
{ .compatible = "microsoft,denali", },
{ .compatible = "microsoft,romulus13", },
{ .compatible = "microsoft,romulus15", },
+ { .compatible = "qcom,glymur-crd" },
{ .compatible = "qcom,hamoa-iot-evk" },
+ { .compatible = "qcom,mahua-crd" },
+ { .compatible = "qcom,purwa-iot-evk" },
{ .compatible = "qcom,sc8180x-primus" },
{ .compatible = "qcom,x1e001de-devkit" },
{ .compatible = "qcom,x1e80100-crd" },
@@ -2467,6 +2471,56 @@ int qcom_scm_qtee_callback_response(phys_addr_t buf, size_t buf_size,
}
EXPORT_SYMBOL(qcom_scm_qtee_callback_response);
+static void qcom_scm_gunyah_wdt_free(void *data)
+{
+ struct platform_device *gunyah_wdt_dev = data;
+
+ platform_device_unregister(gunyah_wdt_dev);
+}
+
+static void qcom_scm_gunyah_wdt_init(struct qcom_scm *scm)
+{
+ struct platform_device *gunyah_wdt_dev;
+ struct device_node *np;
+ bool of_wdt_available;
+ int i;
+ static const uuid_t gunyah_uuid = UUID_INIT(0xc1d58fcd, 0xa453, 0x5fdb,
+ 0x92, 0x65, 0xce, 0x36,
+ 0x67, 0x3d, 0x5f, 0x14);
+ static const char * const of_wdt_compatible[] = {
+ "qcom,kpss-wdt",
+ "arm,sbsa-gwdt",
+ };
+
+ /* Bail out if we are not running under Gunyah */
+ if (!IS_ENABLED(CONFIG_HAVE_ARM_SMCCC_DISCOVERY) ||
+ !arm_smccc_hypervisor_has_uuid(&gunyah_uuid))
+ return;
+
+ /*
+ * Gunyah emulates either of Qualcomm watchdog or ARM SBSA watchdog on
+ * newer platforms. Bail out if we find them in the devicetree.
+ */
+ for (i = 0; i < ARRAY_SIZE(of_wdt_compatible); i++) {
+ np = of_find_compatible_node(NULL, NULL, of_wdt_compatible[i]);
+ of_wdt_available = of_device_is_available(np);
+ of_node_put(np);
+ if (of_wdt_available)
+ return;
+ }
+
+ gunyah_wdt_dev = platform_device_register_simple("gunyah-wdt", -1,
+ NULL, 0);
+ if (IS_ERR(gunyah_wdt_dev)) {
+ dev_err(scm->dev, "Failed to register Gunyah watchdog device: %ld\n",
+ PTR_ERR(gunyah_wdt_dev));
+ return;
+ }
+
+ devm_add_action_or_reset(scm->dev, qcom_scm_gunyah_wdt_free,
+ gunyah_wdt_dev);
+}
+
static void qcom_scm_qtee_free(void *data)
{
struct platform_device *qtee_dev = data;
@@ -2811,6 +2865,9 @@ static int qcom_scm_probe(struct platform_device *pdev)
/* Initialize the QTEE object interface. */
qcom_scm_qtee_init(scm);
+ /* Initialize the Gunyah watchdog platform device. */
+ qcom_scm_gunyah_wdt_init(scm);
+
return 0;
}
diff --git a/drivers/firmware/samsung/exynos-acpm-dvfs.c b/drivers/firmware/samsung/exynos-acpm-dvfs.c
index 1c5b2b143bcc..06bdf62dea1f 100644
--- a/drivers/firmware/samsung/exynos-acpm-dvfs.c
+++ b/drivers/firmware/samsung/exynos-acpm-dvfs.c
@@ -5,6 +5,7 @@
* Copyright 2025 Linaro Ltd.
*/
+#include <linux/array_size.h>
#include <linux/bitfield.h>
#include <linux/firmware/samsung/exynos-acpm-protocol.h>
#include <linux/ktime.h>
@@ -24,12 +25,12 @@ static void acpm_dvfs_set_xfer(struct acpm_xfer *xfer, u32 *cmd, size_t cmdlen,
unsigned int acpm_chan_id, bool response)
{
xfer->acpm_chan_id = acpm_chan_id;
+ xfer->txcnt = cmdlen;
xfer->txd = cmd;
- xfer->txlen = cmdlen;
if (response) {
+ xfer->rxcnt = cmdlen;
xfer->rxd = cmd;
- xfer->rxlen = cmdlen;
}
}
@@ -42,7 +43,7 @@ static void acpm_dvfs_init_set_rate_cmd(u32 cmd[4], unsigned int clk_id,
cmd[3] = ktime_to_ms(ktime_get());
}
-int acpm_dvfs_set_rate(const struct acpm_handle *handle,
+int acpm_dvfs_set_rate(struct acpm_handle *handle,
unsigned int acpm_chan_id, unsigned int clk_id,
unsigned long rate)
{
@@ -50,7 +51,7 @@ int acpm_dvfs_set_rate(const struct acpm_handle *handle,
u32 cmd[4];
acpm_dvfs_init_set_rate_cmd(cmd, clk_id, rate);
- acpm_dvfs_set_xfer(&xfer, cmd, sizeof(cmd), acpm_chan_id, false);
+ acpm_dvfs_set_xfer(&xfer, cmd, ARRAY_SIZE(cmd), acpm_chan_id, false);
return acpm_do_xfer(handle, &xfer);
}
@@ -62,7 +63,7 @@ static void acpm_dvfs_init_get_rate_cmd(u32 cmd[4], unsigned int clk_id)
cmd[3] = ktime_to_ms(ktime_get());
}
-unsigned long acpm_dvfs_get_rate(const struct acpm_handle *handle,
+unsigned long acpm_dvfs_get_rate(struct acpm_handle *handle,
unsigned int acpm_chan_id, unsigned int clk_id)
{
struct acpm_xfer xfer;
@@ -70,7 +71,7 @@ unsigned long acpm_dvfs_get_rate(const struct acpm_handle *handle,
int ret;
acpm_dvfs_init_get_rate_cmd(cmd, clk_id);
- acpm_dvfs_set_xfer(&xfer, cmd, sizeof(cmd), acpm_chan_id, true);
+ acpm_dvfs_set_xfer(&xfer, cmd, ARRAY_SIZE(cmd), acpm_chan_id, true);
ret = acpm_do_xfer(handle, &xfer);
if (ret)
diff --git a/drivers/firmware/samsung/exynos-acpm-dvfs.h b/drivers/firmware/samsung/exynos-acpm-dvfs.h
index 9f2778e649c9..b37b15426102 100644
--- a/drivers/firmware/samsung/exynos-acpm-dvfs.h
+++ b/drivers/firmware/samsung/exynos-acpm-dvfs.h
@@ -11,10 +11,10 @@
struct acpm_handle;
-int acpm_dvfs_set_rate(const struct acpm_handle *handle,
+int acpm_dvfs_set_rate(struct acpm_handle *handle,
unsigned int acpm_chan_id, unsigned int id,
unsigned long rate);
-unsigned long acpm_dvfs_get_rate(const struct acpm_handle *handle,
+unsigned long acpm_dvfs_get_rate(struct acpm_handle *handle,
unsigned int acpm_chan_id,
unsigned int clk_id);
diff --git a/drivers/firmware/samsung/exynos-acpm-pmic.c b/drivers/firmware/samsung/exynos-acpm-pmic.c
index 961d7599e422..0c50993cc9a8 100644
--- a/drivers/firmware/samsung/exynos-acpm-pmic.c
+++ b/drivers/firmware/samsung/exynos-acpm-pmic.c
@@ -41,7 +41,7 @@ static const int acpm_pmic_linux_errmap[] = {
[2] = -EACCES, /* Write register can't be accessed or issues to access it. */
};
-static int acpm_pmic_to_linux_err(int err)
+static int acpm_pmic_to_linux_err(unsigned int err)
{
if (err >= 0 && err < ARRAY_SIZE(acpm_pmic_linux_errmap))
return acpm_pmic_linux_errmap[err];
@@ -63,8 +63,8 @@ static void acpm_pmic_set_xfer(struct acpm_xfer *xfer, u32 *cmd, size_t cmdlen,
{
xfer->txd = cmd;
xfer->rxd = cmd;
- xfer->txlen = cmdlen;
- xfer->rxlen = cmdlen;
+ xfer->txcnt = cmdlen;
+ xfer->rxcnt = cmdlen;
xfer->acpm_chan_id = acpm_chan_id;
}
@@ -77,7 +77,7 @@ static void acpm_pmic_init_read_cmd(u32 cmd[4], u8 type, u8 reg, u8 chan)
cmd[3] = ktime_to_ms(ktime_get());
}
-int acpm_pmic_read_reg(const struct acpm_handle *handle,
+int acpm_pmic_read_reg(struct acpm_handle *handle,
unsigned int acpm_chan_id, u8 type, u8 reg, u8 chan,
u8 *buf)
{
@@ -86,7 +86,7 @@ int acpm_pmic_read_reg(const struct acpm_handle *handle,
int ret;
acpm_pmic_init_read_cmd(cmd, type, reg, chan);
- acpm_pmic_set_xfer(&xfer, cmd, sizeof(cmd), acpm_chan_id);
+ acpm_pmic_set_xfer(&xfer, cmd, ARRAY_SIZE(cmd), acpm_chan_id);
ret = acpm_do_xfer(handle, &xfer);
if (ret)
@@ -107,7 +107,7 @@ static void acpm_pmic_init_bulk_read_cmd(u32 cmd[4], u8 type, u8 reg, u8 chan,
FIELD_PREP(ACPM_PMIC_VALUE, count);
}
-int acpm_pmic_bulk_read(const struct acpm_handle *handle,
+int acpm_pmic_bulk_read(struct acpm_handle *handle,
unsigned int acpm_chan_id, u8 type, u8 reg, u8 chan,
u8 count, u8 *buf)
{
@@ -119,7 +119,7 @@ int acpm_pmic_bulk_read(const struct acpm_handle *handle,
return -EINVAL;
acpm_pmic_init_bulk_read_cmd(cmd, type, reg, chan, count);
- acpm_pmic_set_xfer(&xfer, cmd, sizeof(cmd), acpm_chan_id);
+ acpm_pmic_set_xfer(&xfer, cmd, ARRAY_SIZE(cmd), acpm_chan_id);
ret = acpm_do_xfer(handle, &xfer);
if (ret)
@@ -150,7 +150,7 @@ static void acpm_pmic_init_write_cmd(u32 cmd[4], u8 type, u8 reg, u8 chan,
cmd[3] = ktime_to_ms(ktime_get());
}
-int acpm_pmic_write_reg(const struct acpm_handle *handle,
+int acpm_pmic_write_reg(struct acpm_handle *handle,
unsigned int acpm_chan_id, u8 type, u8 reg, u8 chan,
u8 value)
{
@@ -159,7 +159,7 @@ int acpm_pmic_write_reg(const struct acpm_handle *handle,
int ret;
acpm_pmic_init_write_cmd(cmd, type, reg, chan, value);
- acpm_pmic_set_xfer(&xfer, cmd, sizeof(cmd), acpm_chan_id);
+ acpm_pmic_set_xfer(&xfer, cmd, ARRAY_SIZE(cmd), acpm_chan_id);
ret = acpm_do_xfer(handle, &xfer);
if (ret)
@@ -187,7 +187,7 @@ static void acpm_pmic_init_bulk_write_cmd(u32 cmd[4], u8 type, u8 reg, u8 chan,
}
}
-int acpm_pmic_bulk_write(const struct acpm_handle *handle,
+int acpm_pmic_bulk_write(struct acpm_handle *handle,
unsigned int acpm_chan_id, u8 type, u8 reg, u8 chan,
u8 count, const u8 *buf)
{
@@ -199,7 +199,7 @@ int acpm_pmic_bulk_write(const struct acpm_handle *handle,
return -EINVAL;
acpm_pmic_init_bulk_write_cmd(cmd, type, reg, chan, count, buf);
- acpm_pmic_set_xfer(&xfer, cmd, sizeof(cmd), acpm_chan_id);
+ acpm_pmic_set_xfer(&xfer, cmd, ARRAY_SIZE(cmd), acpm_chan_id);
ret = acpm_do_xfer(handle, &xfer);
if (ret)
@@ -220,7 +220,7 @@ static void acpm_pmic_init_update_cmd(u32 cmd[4], u8 type, u8 reg, u8 chan,
cmd[3] = ktime_to_ms(ktime_get());
}
-int acpm_pmic_update_reg(const struct acpm_handle *handle,
+int acpm_pmic_update_reg(struct acpm_handle *handle,
unsigned int acpm_chan_id, u8 type, u8 reg, u8 chan,
u8 value, u8 mask)
{
@@ -229,7 +229,7 @@ int acpm_pmic_update_reg(const struct acpm_handle *handle,
int ret;
acpm_pmic_init_update_cmd(cmd, type, reg, chan, value, mask);
- acpm_pmic_set_xfer(&xfer, cmd, sizeof(cmd), acpm_chan_id);
+ acpm_pmic_set_xfer(&xfer, cmd, ARRAY_SIZE(cmd), acpm_chan_id);
ret = acpm_do_xfer(handle, &xfer);
if (ret)
diff --git a/drivers/firmware/samsung/exynos-acpm-pmic.h b/drivers/firmware/samsung/exynos-acpm-pmic.h
index 078421888a14..88ae9aada2ae 100644
--- a/drivers/firmware/samsung/exynos-acpm-pmic.h
+++ b/drivers/firmware/samsung/exynos-acpm-pmic.h
@@ -11,19 +11,19 @@
struct acpm_handle;
-int acpm_pmic_read_reg(const struct acpm_handle *handle,
+int acpm_pmic_read_reg(struct acpm_handle *handle,
unsigned int acpm_chan_id, u8 type, u8 reg, u8 chan,
u8 *buf);
-int acpm_pmic_bulk_read(const struct acpm_handle *handle,
+int acpm_pmic_bulk_read(struct acpm_handle *handle,
unsigned int acpm_chan_id, u8 type, u8 reg, u8 chan,
u8 count, u8 *buf);
-int acpm_pmic_write_reg(const struct acpm_handle *handle,
+int acpm_pmic_write_reg(struct acpm_handle *handle,
unsigned int acpm_chan_id, u8 type, u8 reg, u8 chan,
u8 value);
-int acpm_pmic_bulk_write(const struct acpm_handle *handle,
+int acpm_pmic_bulk_write(struct acpm_handle *handle,
unsigned int acpm_chan_id, u8 type, u8 reg, u8 chan,
u8 count, const u8 *buf);
-int acpm_pmic_update_reg(const struct acpm_handle *handle,
+int acpm_pmic_update_reg(struct acpm_handle *handle,
unsigned int acpm_chan_id, u8 type, u8 reg, u8 chan,
u8 value, u8 mask);
#endif /* __EXYNOS_ACPM_PMIC_H__ */
diff --git a/drivers/firmware/samsung/exynos-acpm.c b/drivers/firmware/samsung/exynos-acpm.c
index 0cb269c70460..16c46ed60837 100644
--- a/drivers/firmware/samsung/exynos-acpm.c
+++ b/drivers/firmware/samsung/exynos-acpm.c
@@ -205,7 +205,7 @@ static void acpm_get_saved_rx(struct acpm_chan *achan,
rx_seqnum = FIELD_GET(ACPM_PROTOCOL_SEQNUM, rx_data->cmd[0]);
if (rx_seqnum == tx_seqnum) {
- memcpy(xfer->rxd, rx_data->cmd, xfer->rxlen);
+ memcpy(xfer->rxd, rx_data->cmd, xfer->rxcnt * sizeof(*xfer->rxd));
clear_bit(rx_seqnum - 1, achan->bitmap_seqnum);
}
}
@@ -258,8 +258,7 @@ static int acpm_get_rx(struct acpm_chan *achan, const struct acpm_xfer *xfer)
if (rx_data->response) {
if (rx_seqnum == tx_seqnum) {
- __ioread32_copy(xfer->rxd, addr,
- xfer->rxlen / 4);
+ __ioread32_copy(xfer->rxd, addr, xfer->rxcnt);
rx_set = true;
clear_bit(seqnum, achan->bitmap_seqnum);
} else {
@@ -269,8 +268,7 @@ static int acpm_get_rx(struct acpm_chan *achan, const struct acpm_xfer *xfer)
* clear yet the bitmap. It will be cleared
* after the response is copied to the request.
*/
- __ioread32_copy(rx_data->cmd, addr,
- xfer->rxlen / 4);
+ __ioread32_copy(rx_data->cmd, addr, xfer->rxcnt);
}
} else {
clear_bit(seqnum, achan->bitmap_seqnum);
@@ -412,7 +410,7 @@ static int acpm_wait_for_message_response(struct acpm_chan *achan,
*
* Return: 0 on success, -errno otherwise.
*/
-int acpm_do_xfer(const struct acpm_handle *handle, const struct acpm_xfer *xfer)
+int acpm_do_xfer(struct acpm_handle *handle, const struct acpm_xfer *xfer)
{
struct acpm_info *acpm = handle_to_acpm_info(handle);
struct exynos_mbox_msg msg;
@@ -425,7 +423,9 @@ int acpm_do_xfer(const struct acpm_handle *handle, const struct acpm_xfer *xfer)
achan = &acpm->chans[xfer->acpm_chan_id];
- if (!xfer->txd || xfer->txlen > achan->mlen || xfer->rxlen > achan->mlen)
+ if (!xfer->txd ||
+ (xfer->txcnt * sizeof(*xfer->txd) > achan->mlen) ||
+ (xfer->rxcnt * sizeof(*xfer->rxd) > achan->mlen))
return -EINVAL;
if (!achan->poll_completion) {
@@ -448,7 +448,7 @@ int acpm_do_xfer(const struct acpm_handle *handle, const struct acpm_xfer *xfer)
/* Write TX command. */
__iowrite32_copy(achan->tx.base + achan->mlen * tx_front,
- xfer->txd, xfer->txlen / 4);
+ xfer->txd, xfer->txcnt);
/* Advance TX front. */
writel(idx, achan->tx.front);
@@ -674,7 +674,7 @@ static int acpm_probe(struct platform_device *pdev)
* acpm_handle_put() - release the handle acquired by acpm_get_by_phandle.
* @handle: Handle acquired by acpm_get_by_phandle.
*/
-static void acpm_handle_put(const struct acpm_handle *handle)
+static void acpm_handle_put(struct acpm_handle *handle)
{
struct acpm_info *acpm = handle_to_acpm_info(handle);
struct device *dev = acpm->dev;
@@ -700,9 +700,11 @@ static void devm_acpm_release(struct device *dev, void *res)
* @np: ACPM device tree node.
*
* Return: pointer to handle on success, ERR_PTR(-errno) otherwise.
+ *
+ * Note: handle CANNOT be pointer to const
*/
-static const struct acpm_handle *acpm_get_by_node(struct device *dev,
- struct device_node *np)
+static struct acpm_handle *acpm_get_by_node(struct device *dev,
+ struct device_node *np)
{
struct platform_device *pdev;
struct device_link *link;
@@ -743,10 +745,10 @@ static const struct acpm_handle *acpm_get_by_node(struct device *dev,
*
* Return: pointer to handle on success, ERR_PTR(-errno) otherwise.
*/
-const struct acpm_handle *devm_acpm_get_by_node(struct device *dev,
- struct device_node *np)
+struct acpm_handle *devm_acpm_get_by_node(struct device *dev,
+ struct device_node *np)
{
- const struct acpm_handle **ptr, *handle;
+ struct acpm_handle **ptr, *handle;
ptr = devres_alloc(devm_acpm_release, sizeof(*ptr), GFP_KERNEL);
if (!ptr)
diff --git a/drivers/firmware/samsung/exynos-acpm.h b/drivers/firmware/samsung/exynos-acpm.h
index 2d14cb58f98c..5df8354dc96c 100644
--- a/drivers/firmware/samsung/exynos-acpm.h
+++ b/drivers/firmware/samsung/exynos-acpm.h
@@ -8,16 +8,16 @@
#define __EXYNOS_ACPM_H__
struct acpm_xfer {
- const u32 *txd;
- u32 *rxd;
- size_t txlen;
- size_t rxlen;
+ const u32 *txd __counted_by_ptr(txcnt);
+ u32 *rxd __counted_by_ptr(rxcnt);
+ size_t txcnt;
+ size_t rxcnt;
unsigned int acpm_chan_id;
};
struct acpm_handle;
-int acpm_do_xfer(const struct acpm_handle *handle,
+int acpm_do_xfer(struct acpm_handle *handle,
const struct acpm_xfer *xfer);
#endif /* __EXYNOS_ACPM_H__ */
diff --git a/drivers/firmware/tegra/bpmp.c b/drivers/firmware/tegra/bpmp.c
index e74bba7ccc44..753472b53bd8 100644
--- a/drivers/firmware/tegra/bpmp.c
+++ b/drivers/firmware/tegra/bpmp.c
@@ -32,6 +32,40 @@ channel_to_ops(struct tegra_bpmp_channel *channel)
return bpmp->soc->ops;
}
+struct tegra_bpmp *tegra_bpmp_get_with_id(struct device *dev, unsigned int *id)
+{
+ struct platform_device *pdev;
+ struct of_phandle_args args;
+ struct tegra_bpmp *bpmp;
+ int err;
+
+ err = __of_parse_phandle_with_args(dev->of_node, "nvidia,bpmp", NULL,
+ 1, 0, &args);
+ if (err < 0)
+ return ERR_PTR(err);
+
+ pdev = of_find_device_by_node(args.np);
+ if (!pdev) {
+ bpmp = ERR_PTR(-ENODEV);
+ goto put;
+ }
+
+ bpmp = platform_get_drvdata(pdev);
+ if (!bpmp) {
+ bpmp = ERR_PTR(-EPROBE_DEFER);
+ put_device(&pdev->dev);
+ goto put;
+ }
+
+ if (id)
+ *id = args.args[0];
+
+put:
+ of_node_put(args.np);
+ return bpmp;
+}
+EXPORT_SYMBOL_GPL(tegra_bpmp_get_with_id);
+
struct tegra_bpmp *tegra_bpmp_get(struct device *dev)
{
struct platform_device *pdev;
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index c5ede0e4a32a..020e51e30317 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -580,6 +580,7 @@ config GPIO_PL061
config GPIO_POLARFIRE_SOC
bool "Microchip FPGA GPIO support"
select REGMAP_MMIO
+ select GPIOLIB_IRQCHIP
help
Say yes here to support the GPIO controllers on Microchip FPGAs.
diff --git a/drivers/gpio/gpio-mpfs.c b/drivers/gpio/gpio-mpfs.c
index 9468795b9634..1a4cf213c723 100644
--- a/drivers/gpio/gpio-mpfs.c
+++ b/drivers/gpio/gpio-mpfs.c
@@ -9,8 +9,9 @@
#include <linux/device.h>
#include <linux/errno.h>
#include <linux/gpio/driver.h>
-#include <linux/init.h>
+#include <linux/interrupt.h>
#include <linux/mod_devicetable.h>
+#include <linux/of_irq.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/regmap.h>
@@ -18,7 +19,7 @@
#define MPFS_GPIO_CTRL(i) (0x4 * (i))
#define MPFS_MAX_NUM_GPIO 32
-#define MPFS_GPIO_EN_INT 3
+#define MPFS_GPIO_EN_INT BIT(3)
#define MPFS_GPIO_EN_OUT_BUF BIT(2)
#define MPFS_GPIO_EN_IN BIT(1)
#define MPFS_GPIO_EN_OUT BIT(0)
@@ -52,6 +53,7 @@ static const struct regmap_config mpfs_gpio_regmap_config = {
.reg_bits = 32,
.reg_stride = 4,
.val_bits = 32,
+ .use_raw_spinlock = true,
};
static int mpfs_gpio_direction_input(struct gpio_chip *gc, unsigned int gpio_index)
@@ -114,13 +116,98 @@ static int mpfs_gpio_set(struct gpio_chip *gc, unsigned int gpio_index, int valu
return ret;
}
+static int mpfs_gpio_irq_set_type(struct irq_data *data, unsigned int type)
+{
+ struct gpio_chip *gc = irq_data_get_irq_chip_data(data);
+ struct mpfs_gpio_chip *mpfs_gpio = gpiochip_get_data(gc);
+ int gpio_index = irqd_to_hwirq(data) % 32;
+ u32 interrupt_type;
+
+ switch (type) {
+ case IRQ_TYPE_EDGE_BOTH:
+ interrupt_type = MPFS_GPIO_TYPE_INT_EDGE_BOTH;
+ break;
+ case IRQ_TYPE_EDGE_FALLING:
+ interrupt_type = MPFS_GPIO_TYPE_INT_EDGE_NEG;
+ break;
+ case IRQ_TYPE_EDGE_RISING:
+ interrupt_type = MPFS_GPIO_TYPE_INT_EDGE_POS;
+ break;
+ case IRQ_TYPE_LEVEL_HIGH:
+ interrupt_type = MPFS_GPIO_TYPE_INT_LEVEL_HIGH;
+ break;
+ case IRQ_TYPE_LEVEL_LOW:
+ interrupt_type = MPFS_GPIO_TYPE_INT_LEVEL_LOW;
+ break;
+ }
+
+ regmap_update_bits(mpfs_gpio->regs, MPFS_GPIO_CTRL(gpio_index),
+ MPFS_GPIO_TYPE_INT_MASK, interrupt_type);
+
+ return 0;
+}
+
+static void mpfs_gpio_irq_unmask(struct irq_data *data)
+{
+ struct gpio_chip *gc = irq_data_get_irq_chip_data(data);
+ struct mpfs_gpio_chip *mpfs_gpio = gpiochip_get_data(gc);
+ int gpio_index = irqd_to_hwirq(data) % 32;
+
+ gpiochip_enable_irq(gc, gpio_index);
+ mpfs_gpio_direction_input(gc, gpio_index);
+ regmap_update_bits(mpfs_gpio->regs, MPFS_GPIO_CTRL(gpio_index),
+ MPFS_GPIO_EN_INT, MPFS_GPIO_EN_INT);
+}
+
+static void mpfs_gpio_irq_mask(struct irq_data *data)
+{
+ struct gpio_chip *gc = irq_data_get_irq_chip_data(data);
+ struct mpfs_gpio_chip *mpfs_gpio = gpiochip_get_data(gc);
+ int gpio_index = irqd_to_hwirq(data) % 32;
+
+ regmap_update_bits(mpfs_gpio->regs, MPFS_GPIO_CTRL(gpio_index),
+ MPFS_GPIO_EN_INT, 0);
+ gpiochip_disable_irq(gc, gpio_index);
+}
+
+static const struct irq_chip mpfs_gpio_irqchip = {
+ .name = "MPFS GPIO",
+ .irq_set_type = mpfs_gpio_irq_set_type,
+ .irq_mask = mpfs_gpio_irq_mask,
+ .irq_unmask = mpfs_gpio_irq_unmask,
+ .flags = IRQCHIP_IMMUTABLE | IRQCHIP_MASK_ON_SUSPEND,
+ GPIOCHIP_IRQ_RESOURCE_HELPERS,
+};
+
+static void mpfs_gpio_irq_handler(struct irq_desc *desc)
+{
+ struct irq_chip *irqchip = irq_desc_get_chip(desc);
+ struct mpfs_gpio_chip *mpfs_gpio = irq_desc_get_handler_data(desc);
+ unsigned long status;
+ u32 val;
+ int i;
+
+ chained_irq_enter(irqchip, desc);
+
+ regmap_read(mpfs_gpio->regs, MPFS_IRQ_REG, &val);
+ status = val;
+ for_each_set_bit(i, &status, MPFS_MAX_NUM_GPIO) {
+ regmap_write(mpfs_gpio->regs, MPFS_IRQ_REG, BIT(i));
+ generic_handle_domain_irq(mpfs_gpio->gc.irq.domain, i);
+ }
+
+ chained_irq_exit(irqchip, desc);
+}
+
static int mpfs_gpio_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
+ struct device_node *node = dev->of_node;
struct mpfs_gpio_chip *mpfs_gpio;
+ struct gpio_irq_chip *girq;
struct clk *clk;
void __iomem *base;
- int ngpios;
+ int ngpios, nirqs, ret;
mpfs_gpio = devm_kzalloc(dev, sizeof(*mpfs_gpio), GFP_KERNEL);
if (!mpfs_gpio)
@@ -157,6 +244,35 @@ static int mpfs_gpio_probe(struct platform_device *pdev)
mpfs_gpio->gc.parent = dev;
mpfs_gpio->gc.owner = THIS_MODULE;
+ nirqs = of_irq_count(node);
+ if (nirqs > MPFS_MAX_NUM_GPIO)
+ return -ENXIO;
+
+ if (nirqs) {
+ girq = &mpfs_gpio->gc.irq;
+
+ gpio_irq_chip_set_chip(girq, &mpfs_gpio_irqchip);
+
+ girq->num_parents = nirqs;
+ girq->parents = devm_kcalloc(&pdev->dev, girq->num_parents,
+ sizeof(*girq->parents), GFP_KERNEL);
+ if (!girq->parents)
+ return -ENOMEM;
+
+ for (int i = 0; i < nirqs; i++) {
+ ret = platform_get_irq(pdev, i);
+ if (ret < 0)
+ return ret;
+
+ girq->parents[i] = ret;
+ girq->parent_handler_data = mpfs_gpio;
+ girq->parent_handler = mpfs_gpio_irq_handler;
+ }
+
+ girq->handler = handle_level_irq;
+ girq->default_type = IRQ_TYPE_NONE;
+ }
+
return devm_gpiochip_add_data(dev, &mpfs_gpio->gc, mpfs_gpio);
}
diff --git a/drivers/memory/Kconfig b/drivers/memory/Kconfig
index 79df0d22e218..e5527020ff33 100644
--- a/drivers/memory/Kconfig
+++ b/drivers/memory/Kconfig
@@ -64,17 +64,6 @@ config BRCMSTB_MEMC
controller and specifically control the Self Refresh Power Down
(SRPD) inactivity timeout.
-config BT1_L2_CTL
- bool "Baikal-T1 CM2 L2-RAM Cache Control Block"
- depends on MIPS_BAIKAL_T1 || COMPILE_TEST
- select MFD_SYSCON
- help
- Baikal-T1 CPU is based on the MIPS P5600 Warrior IP-core. The CPU
- resides Coherency Manager v2 with embedded 1MB L2-cache. It's
- possible to tune the L2 cache performance up by setting the data,
- tags and way-select latencies of RAM access. This driver provides a
- dt properties-based and sysfs interface for it.
-
config TI_AEMIF
tristate "Texas Instruments AEMIF driver"
depends on ARCH_DAVINCI || ARCH_KEYSTONE || COMPILE_TEST
diff --git a/drivers/memory/Makefile b/drivers/memory/Makefile
index c1959661bf63..3ee883c8759a 100644
--- a/drivers/memory/Makefile
+++ b/drivers/memory/Makefile
@@ -11,7 +11,6 @@ obj-$(CONFIG_ARM_PL172_MPMC) += pl172.o
obj-$(CONFIG_ATMEL_EBI) += atmel-ebi.o
obj-$(CONFIG_BRCMSTB_DPFE) += brcmstb_dpfe.o
obj-$(CONFIG_BRCMSTB_MEMC) += brcmstb_memc.o
-obj-$(CONFIG_BT1_L2_CTL) += bt1-l2-ctl.o
obj-$(CONFIG_TI_AEMIF) += ti-aemif.o
obj-$(CONFIG_TI_EMIF) += emif.o
obj-$(CONFIG_OMAP_GPMC) += omap-gpmc.o
diff --git a/drivers/memory/brcmstb_memc.c b/drivers/memory/brcmstb_memc.c
index ba73470b1b13..c28fe9093616 100644
--- a/drivers/memory/brcmstb_memc.c
+++ b/drivers/memory/brcmstb_memc.c
@@ -14,6 +14,7 @@
#define REG_MEMC_CNTRLR_CONFIG 0x00
#define CNTRLR_CONFIG_LPDDR4_SHIFT 5
+#define CNTRLR_CONFIG_LPDDR5_SHIFT 6
#define CNTRLR_CONFIG_MASK 0xf
#define REG_MEMC_SRPD_CFG_21 0x20
#define REG_MEMC_SRPD_CFG_20 0x34
@@ -34,14 +35,15 @@ struct brcmstb_memc {
u32 srpd_offset;
};
-static int brcmstb_memc_uses_lpddr4(struct brcmstb_memc *memc)
+static int brcmstb_memc_uses_lpddr45(struct brcmstb_memc *memc)
{
void __iomem *config = memc->ddr_ctrl + REG_MEMC_CNTRLR_CONFIG;
u32 reg;
reg = readl_relaxed(config) & CNTRLR_CONFIG_MASK;
- return reg == CNTRLR_CONFIG_LPDDR4_SHIFT;
+ return reg == CNTRLR_CONFIG_LPDDR4_SHIFT ||
+ reg == CNTRLR_CONFIG_LPDDR5_SHIFT;
}
static int brcmstb_memc_srpd_config(struct brcmstb_memc *memc,
@@ -95,7 +97,7 @@ static ssize_t srpd_store(struct device *dev, struct device_attribute *attr,
* dynamic tuning process will also get affected by the inactivity
* timeout, thus making it non functional.
*/
- if (brcmstb_memc_uses_lpddr4(memc))
+ if (brcmstb_memc_uses_lpddr45(memc))
return -EOPNOTSUPP;
ret = kstrtouint(buf, 10, &val);
diff --git a/drivers/memory/bt1-l2-ctl.c b/drivers/memory/bt1-l2-ctl.c
deleted file mode 100644
index 0fd96abc172a..000000000000
--- a/drivers/memory/bt1-l2-ctl.c
+++ /dev/null
@@ -1,323 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (C) 2020 BAIKAL ELECTRONICS, JSC
- *
- * Authors:
- * Serge Semin <Sergey.Semin@baikalelectronics.ru>
- *
- * Baikal-T1 CM2 L2-cache Control Block driver.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/bitfield.h>
-#include <linux/types.h>
-#include <linux/device.h>
-#include <linux/platform_device.h>
-#include <linux/regmap.h>
-#include <linux/mfd/syscon.h>
-#include <linux/sysfs.h>
-#include <linux/of.h>
-
-#define L2_CTL_REG 0x028
-#define L2_CTL_DATA_STALL_FLD 0
-#define L2_CTL_DATA_STALL_MASK GENMASK(1, L2_CTL_DATA_STALL_FLD)
-#define L2_CTL_TAG_STALL_FLD 2
-#define L2_CTL_TAG_STALL_MASK GENMASK(3, L2_CTL_TAG_STALL_FLD)
-#define L2_CTL_WS_STALL_FLD 4
-#define L2_CTL_WS_STALL_MASK GENMASK(5, L2_CTL_WS_STALL_FLD)
-#define L2_CTL_SET_CLKRATIO BIT(13)
-#define L2_CTL_CLKRATIO_LOCK BIT(31)
-
-#define L2_CTL_STALL_MIN 0
-#define L2_CTL_STALL_MAX 3
-#define L2_CTL_STALL_SET_DELAY_US 1
-#define L2_CTL_STALL_SET_TOUT_US 1000
-
-/*
- * struct l2_ctl - Baikal-T1 L2 Control block private data.
- * @dev: Pointer to the device structure.
- * @sys_regs: Baikal-T1 System Controller registers map.
- */
-struct l2_ctl {
- struct device *dev;
-
- struct regmap *sys_regs;
-};
-
-/*
- * enum l2_ctl_stall - Baikal-T1 L2-cache-RAM stall identifier.
- * @L2_WSSTALL: Way-select latency.
- * @L2_TAGSTALL: Tag latency.
- * @L2_DATASTALL: Data latency.
- */
-enum l2_ctl_stall {
- L2_WS_STALL,
- L2_TAG_STALL,
- L2_DATA_STALL
-};
-
-/*
- * struct l2_ctl_device_attribute - Baikal-T1 L2-cache device attribute.
- * @dev_attr: Actual sysfs device attribute.
- * @id: L2-cache stall field identifier.
- */
-struct l2_ctl_device_attribute {
- struct device_attribute dev_attr;
- enum l2_ctl_stall id;
-};
-
-#define to_l2_ctl_dev_attr(_dev_attr) \
- container_of(_dev_attr, struct l2_ctl_device_attribute, dev_attr)
-
-#define L2_CTL_ATTR_RW(_name, _prefix, _id) \
- struct l2_ctl_device_attribute l2_ctl_attr_##_name = \
- { __ATTR(_name, 0644, _prefix##_show, _prefix##_store), _id }
-
-static int l2_ctl_get_latency(struct l2_ctl *l2, enum l2_ctl_stall id, u32 *val)
-{
- u32 data = 0;
- int ret;
-
- ret = regmap_read(l2->sys_regs, L2_CTL_REG, &data);
- if (ret)
- return ret;
-
- switch (id) {
- case L2_WS_STALL:
- *val = FIELD_GET(L2_CTL_WS_STALL_MASK, data);
- break;
- case L2_TAG_STALL:
- *val = FIELD_GET(L2_CTL_TAG_STALL_MASK, data);
- break;
- case L2_DATA_STALL:
- *val = FIELD_GET(L2_CTL_DATA_STALL_MASK, data);
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int l2_ctl_set_latency(struct l2_ctl *l2, enum l2_ctl_stall id, u32 val)
-{
- u32 mask = 0, data = 0;
- int ret;
-
- val = clamp_val(val, L2_CTL_STALL_MIN, L2_CTL_STALL_MAX);
-
- switch (id) {
- case L2_WS_STALL:
- data = FIELD_PREP(L2_CTL_WS_STALL_MASK, val);
- mask = L2_CTL_WS_STALL_MASK;
- break;
- case L2_TAG_STALL:
- data = FIELD_PREP(L2_CTL_TAG_STALL_MASK, val);
- mask = L2_CTL_TAG_STALL_MASK;
- break;
- case L2_DATA_STALL:
- data = FIELD_PREP(L2_CTL_DATA_STALL_MASK, val);
- mask = L2_CTL_DATA_STALL_MASK;
- break;
- default:
- return -EINVAL;
- }
-
- data |= L2_CTL_SET_CLKRATIO;
- mask |= L2_CTL_SET_CLKRATIO;
-
- ret = regmap_update_bits(l2->sys_regs, L2_CTL_REG, mask, data);
- if (ret)
- return ret;
-
- return regmap_read_poll_timeout(l2->sys_regs, L2_CTL_REG, data,
- data & L2_CTL_CLKRATIO_LOCK,
- L2_CTL_STALL_SET_DELAY_US,
- L2_CTL_STALL_SET_TOUT_US);
-}
-
-static void l2_ctl_clear_data(void *data)
-{
- struct l2_ctl *l2 = data;
- struct platform_device *pdev = to_platform_device(l2->dev);
-
- platform_set_drvdata(pdev, NULL);
-}
-
-static struct l2_ctl *l2_ctl_create_data(struct platform_device *pdev)
-{
- struct device *dev = &pdev->dev;
- struct l2_ctl *l2;
- int ret;
-
- l2 = devm_kzalloc(dev, sizeof(*l2), GFP_KERNEL);
- if (!l2)
- return ERR_PTR(-ENOMEM);
-
- ret = devm_add_action(dev, l2_ctl_clear_data, l2);
- if (ret) {
- dev_err(dev, "Can't add L2 CTL data clear action\n");
- return ERR_PTR(ret);
- }
-
- l2->dev = dev;
- platform_set_drvdata(pdev, l2);
-
- return l2;
-}
-
-static int l2_ctl_find_sys_regs(struct l2_ctl *l2)
-{
- l2->sys_regs = syscon_node_to_regmap(l2->dev->of_node->parent);
- if (IS_ERR(l2->sys_regs)) {
- dev_err(l2->dev, "Couldn't get L2 CTL register map\n");
- return PTR_ERR(l2->sys_regs);
- }
-
- return 0;
-}
-
-static int l2_ctl_of_parse_property(struct l2_ctl *l2, enum l2_ctl_stall id,
- const char *propname)
-{
- int ret = 0;
- u32 data;
-
- if (!of_property_read_u32(l2->dev->of_node, propname, &data)) {
- ret = l2_ctl_set_latency(l2, id, data);
- if (ret)
- dev_err(l2->dev, "Invalid value of '%s'\n", propname);
- }
-
- return ret;
-}
-
-static int l2_ctl_of_parse(struct l2_ctl *l2)
-{
- int ret;
-
- ret = l2_ctl_of_parse_property(l2, L2_WS_STALL, "baikal,l2-ws-latency");
- if (ret)
- return ret;
-
- ret = l2_ctl_of_parse_property(l2, L2_TAG_STALL, "baikal,l2-tag-latency");
- if (ret)
- return ret;
-
- return l2_ctl_of_parse_property(l2, L2_DATA_STALL,
- "baikal,l2-data-latency");
-}
-
-static ssize_t l2_ctl_latency_show(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct l2_ctl_device_attribute *devattr = to_l2_ctl_dev_attr(attr);
- struct l2_ctl *l2 = dev_get_drvdata(dev);
- u32 data;
- int ret;
-
- ret = l2_ctl_get_latency(l2, devattr->id, &data);
- if (ret)
- return ret;
-
- return sysfs_emit(buf, "%u\n", data);
-}
-
-static ssize_t l2_ctl_latency_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct l2_ctl_device_attribute *devattr = to_l2_ctl_dev_attr(attr);
- struct l2_ctl *l2 = dev_get_drvdata(dev);
- u32 data;
- int ret;
-
- if (kstrtouint(buf, 0, &data) < 0)
- return -EINVAL;
-
- ret = l2_ctl_set_latency(l2, devattr->id, data);
- if (ret)
- return ret;
-
- return count;
-}
-
-static L2_CTL_ATTR_RW(l2_ws_latency, l2_ctl_latency, L2_WS_STALL);
-static L2_CTL_ATTR_RW(l2_tag_latency, l2_ctl_latency, L2_TAG_STALL);
-static L2_CTL_ATTR_RW(l2_data_latency, l2_ctl_latency, L2_DATA_STALL);
-
-static struct attribute *l2_ctl_sysfs_attrs[] = {
- &l2_ctl_attr_l2_ws_latency.dev_attr.attr,
- &l2_ctl_attr_l2_tag_latency.dev_attr.attr,
- &l2_ctl_attr_l2_data_latency.dev_attr.attr,
- NULL
-};
-ATTRIBUTE_GROUPS(l2_ctl_sysfs);
-
-static void l2_ctl_remove_sysfs(void *data)
-{
- struct l2_ctl *l2 = data;
-
- device_remove_groups(l2->dev, l2_ctl_sysfs_groups);
-}
-
-static int l2_ctl_init_sysfs(struct l2_ctl *l2)
-{
- int ret;
-
- ret = device_add_groups(l2->dev, l2_ctl_sysfs_groups);
- if (ret) {
- dev_err(l2->dev, "Failed to create L2 CTL sysfs nodes\n");
- return ret;
- }
-
- ret = devm_add_action_or_reset(l2->dev, l2_ctl_remove_sysfs, l2);
- if (ret)
- dev_err(l2->dev, "Can't add L2 CTL sysfs remove action\n");
-
- return ret;
-}
-
-static int l2_ctl_probe(struct platform_device *pdev)
-{
- struct l2_ctl *l2;
- int ret;
-
- l2 = l2_ctl_create_data(pdev);
- if (IS_ERR(l2))
- return PTR_ERR(l2);
-
- ret = l2_ctl_find_sys_regs(l2);
- if (ret)
- return ret;
-
- ret = l2_ctl_of_parse(l2);
- if (ret)
- return ret;
-
- ret = l2_ctl_init_sysfs(l2);
- if (ret)
- return ret;
-
- return 0;
-}
-
-static const struct of_device_id l2_ctl_of_match[] = {
- { .compatible = "baikal,bt1-l2-ctl" },
- { }
-};
-MODULE_DEVICE_TABLE(of, l2_ctl_of_match);
-
-static struct platform_driver l2_ctl_driver = {
- .probe = l2_ctl_probe,
- .driver = {
- .name = "bt1-l2-ctl",
- .of_match_table = l2_ctl_of_match
- }
-};
-module_platform_driver(l2_ctl_driver);
-
-MODULE_AUTHOR("Serge Semin <Sergey.Semin@baikalelectronics.ru>");
-MODULE_DESCRIPTION("Baikal-T1 L2-cache driver");
diff --git a/drivers/memory/renesas-rpc-if.c b/drivers/memory/renesas-rpc-if.c
index 58ccc1c02e90..0fb568456164 100644
--- a/drivers/memory/renesas-rpc-if.c
+++ b/drivers/memory/renesas-rpc-if.c
@@ -1005,11 +1005,9 @@ static int rpcif_probe(struct platform_device *pdev)
return PTR_ERR(rpc->base);
rpc->info = of_device_get_match_data(dev);
rpc->regmap = devm_regmap_init(dev, NULL, rpc, rpc->info->regmap_config);
- if (IS_ERR(rpc->regmap)) {
- dev_err(dev, "failed to init regmap for rpcif, error %ld\n",
- PTR_ERR(rpc->regmap));
- return PTR_ERR(rpc->regmap);
- }
+ if (IS_ERR(rpc->regmap))
+ return dev_err_probe(dev, PTR_ERR(rpc->regmap),
+ "failed to init regmap for rpcif\n");
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dirmap");
rpc->dirmap = devm_ioremap_resource(dev, res);
diff --git a/drivers/memory/tegra/mc.c b/drivers/memory/tegra/mc.c
index 6edb210287dc..d620660da331 100644
--- a/drivers/memory/tegra/mc.c
+++ b/drivers/memory/tegra/mc.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
- * Copyright (C) 2014-2025 NVIDIA CORPORATION. All rights reserved.
+ * Copyright (C) 2014-2026 NVIDIA CORPORATION. All rights reserved.
*/
#include <linux/clk.h>
@@ -56,6 +56,23 @@ static const struct of_device_id tegra_mc_of_match[] = {
};
MODULE_DEVICE_TABLE(of, tegra_mc_of_match);
+const struct tegra_mc_regs tegra20_mc_regs = {
+ .cfg_channel_enable = 0xdf8,
+ .err_status = 0x08,
+ .err_add = 0x0c,
+ .err_add_hi = 0x11fc,
+ .err_vpr_status = 0x654,
+ .err_vpr_add = 0x658,
+ .err_sec_status = 0x67c,
+ .err_sec_add = 0x680,
+ .err_mts_status = 0x9b0,
+ .err_mts_add = 0x9b4,
+ .err_gen_co_status = 0xc00,
+ .err_gen_co_add = 0xc04,
+ .err_route_status = 0x9c0,
+ .err_route_add = 0x9c4,
+};
+
static void tegra_mc_devm_action_put_device(void *data)
{
struct tegra_mc *mc = data;
@@ -381,12 +398,16 @@ unsigned int tegra_mc_get_emem_device_count(struct tegra_mc *mc)
}
EXPORT_SYMBOL_GPL(tegra_mc_get_emem_device_count);
+const irq_handler_t tegra30_mc_irq_handlers[] = {
+ tegra30_mc_handle_irq
+};
+
#if defined(CONFIG_ARCH_TEGRA_3x_SOC) || \
defined(CONFIG_ARCH_TEGRA_114_SOC) || \
defined(CONFIG_ARCH_TEGRA_124_SOC) || \
defined(CONFIG_ARCH_TEGRA_132_SOC) || \
defined(CONFIG_ARCH_TEGRA_210_SOC)
-static int tegra_mc_setup_latency_allowance(struct tegra_mc *mc)
+static void tegra_mc_setup_latency_allowance(struct tegra_mc *mc)
{
unsigned long long tick;
unsigned int i;
@@ -414,8 +435,6 @@ static int tegra_mc_setup_latency_allowance(struct tegra_mc *mc)
/* latch new values */
mc_writel(mc, MC_TIMING_UPDATE, MC_TIMING_CONTROL);
-
- return 0;
}
static int load_one_timing(struct tegra_mc *mc,
@@ -509,32 +528,24 @@ int tegra30_mc_probe(struct tegra_mc *mc)
int err;
mc->clk = devm_clk_get_optional(mc->dev, "mc");
- if (IS_ERR(mc->clk)) {
- dev_err(mc->dev, "failed to get MC clock: %ld\n", PTR_ERR(mc->clk));
- return PTR_ERR(mc->clk);
- }
+ if (IS_ERR(mc->clk))
+ return dev_err_probe(mc->dev, PTR_ERR(mc->clk),
+ "failed to get MC clock\n");
/* ensure that debug features are disabled */
mc_writel(mc, 0x00000000, MC_TIMING_CONTROL_DBG);
- err = tegra_mc_setup_latency_allowance(mc);
- if (err < 0) {
- dev_err(mc->dev, "failed to setup latency allowance: %d\n", err);
- return err;
- }
+ tegra_mc_setup_latency_allowance(mc);
err = tegra_mc_setup_timings(mc);
- if (err < 0) {
- dev_err(mc->dev, "failed to setup timings: %d\n", err);
- return err;
- }
+ if (err < 0)
+ return dev_err_probe(mc->dev, err, "failed to setup timings\n");
return 0;
}
const struct tegra_mc_ops tegra30_mc_ops = {
.probe = tegra30_mc_probe,
- .handle_irq = tegra30_mc_handle_irq,
};
#endif
@@ -575,9 +586,9 @@ irqreturn_t tegra30_mc_handle_irq(int irq, void *data)
}
/* mask all interrupts to avoid flooding */
- status = mc_ch_readl(mc, channel, MC_INTSTATUS) & mc->soc->intmask;
+ status = mc_ch_readl(mc, channel, MC_INTSTATUS) & mc->soc->intmasks[0].mask;
} else {
- status = mc_readl(mc, MC_INTSTATUS) & mc->soc->intmask;
+ status = mc_readl(mc, MC_INTSTATUS) & mc->soc->intmasks[0].mask;
}
if (!status)
@@ -600,37 +611,37 @@ irqreturn_t tegra30_mc_handle_irq(int irq, void *data)
switch (intmask) {
case MC_INT_DECERR_VPR:
- status_reg = MC_ERR_VPR_STATUS;
- addr_reg = MC_ERR_VPR_ADR;
+ status_reg = mc->soc->regs->err_vpr_status;
+ addr_reg = mc->soc->regs->err_vpr_add;
break;
case MC_INT_SECERR_SEC:
- status_reg = MC_ERR_SEC_STATUS;
- addr_reg = MC_ERR_SEC_ADR;
+ status_reg = mc->soc->regs->err_sec_status;
+ addr_reg = mc->soc->regs->err_sec_add;
break;
case MC_INT_DECERR_MTS:
- status_reg = MC_ERR_MTS_STATUS;
- addr_reg = MC_ERR_MTS_ADR;
+ status_reg = mc->soc->regs->err_mts_status;
+ addr_reg = mc->soc->regs->err_mts_add;
break;
case MC_INT_DECERR_GENERALIZED_CARVEOUT:
- status_reg = MC_ERR_GENERALIZED_CARVEOUT_STATUS;
- addr_reg = MC_ERR_GENERALIZED_CARVEOUT_ADR;
+ status_reg = mc->soc->regs->err_gen_co_status;
+ addr_reg = mc->soc->regs->err_gen_co_add;
break;
case MC_INT_DECERR_ROUTE_SANITY:
- status_reg = MC_ERR_ROUTE_SANITY_STATUS;
- addr_reg = MC_ERR_ROUTE_SANITY_ADR;
+ status_reg = mc->soc->regs->err_route_status;
+ addr_reg = mc->soc->regs->err_route_add;
break;
default:
- status_reg = MC_ERR_STATUS;
- addr_reg = MC_ERR_ADR;
+ status_reg = mc->soc->regs->err_status;
+ addr_reg = mc->soc->regs->err_add;
#ifdef CONFIG_PHYS_ADDR_T_64BIT
if (mc->soc->has_addr_hi_reg)
- addr_hi_reg = MC_ERR_ADR_HI;
+ addr_hi_reg = mc->soc->regs->err_add_hi;
#endif
break;
}
@@ -647,9 +658,12 @@ irqreturn_t tegra30_mc_handle_irq(int irq, void *data)
addr = mc_ch_readl(mc, channel, addr_hi_reg);
else
addr = mc_readl(mc, addr_hi_reg);
- } else {
+ } else if (mc->soc->mc_addr_hi_mask) {
addr = ((value >> MC_ERR_STATUS_ADR_HI_SHIFT) &
- MC_ERR_STATUS_ADR_HI_MASK);
+ mc->soc->mc_addr_hi_mask);
+ } else {
+ dev_err_ratelimited(mc->dev, "Unable to determine high address!");
+ return IRQ_NONE;
}
addr <<= 32;
}
@@ -674,11 +688,11 @@ irqreturn_t tegra30_mc_handle_irq(int irq, void *data)
}
}
- type = (value & MC_ERR_STATUS_TYPE_MASK) >>
+ type = (value & mc->soc->mc_err_status_type_mask) >>
MC_ERR_STATUS_TYPE_SHIFT;
- desc = tegra_mc_error_names[type];
+ desc = tegra20_mc_error_names[type];
- switch (value & MC_ERR_STATUS_TYPE_MASK) {
+ switch (value & mc->soc->mc_err_status_type_mask) {
case MC_ERR_STATUS_TYPE_INVALID_SMMU_PAGE:
perm[0] = ' ';
perm[1] = '[';
@@ -744,9 +758,10 @@ const char *const tegra_mc_status_names[32] = {
[16] = "MTS carveout violation",
[17] = "Generalized carveout violation",
[20] = "Route Sanity error",
+ [21] = "GIC_MSI error",
};
-const char *const tegra_mc_error_names[8] = {
+const char *const tegra20_mc_error_names[8] = {
[2] = "EMEM decode error",
[3] = "TrustZone violation",
[4] = "Carveout violation",
@@ -883,7 +898,7 @@ static void tegra_mc_num_channel_enabled(struct tegra_mc *mc)
unsigned int i;
u32 value;
- value = mc_ch_readl(mc, 0, MC_EMEM_ADR_CFG_CHANNEL_ENABLE);
+ value = mc_ch_readl(mc, 0, mc->soc->regs->cfg_channel_enable);
if (value <= 0) {
mc->num_channels = mc->soc->num_channels;
return;
@@ -935,25 +950,32 @@ static int tegra_mc_probe(struct platform_device *pdev)
tegra_mc_num_channel_enabled(mc);
- if (mc->soc->ops && mc->soc->ops->handle_irq) {
- mc->irq = platform_get_irq(pdev, 0);
- if (mc->irq < 0)
- return mc->irq;
+ if (mc->soc->handle_irq) {
+ unsigned int i;
WARN(!mc->soc->client_id_mask, "missing client ID mask for this SoC\n");
- if (mc->soc->num_channels)
- mc_ch_writel(mc, MC_BROADCAST_CHANNEL, mc->soc->intmask,
- MC_INTMASK);
- else
- mc_writel(mc, mc->soc->intmask, MC_INTMASK);
+ for (i = 0; i < mc->soc->num_interrupts; i++) {
+ int irq;
- err = devm_request_irq(&pdev->dev, mc->irq, mc->soc->ops->handle_irq, 0,
- dev_name(&pdev->dev), mc);
- if (err < 0) {
- dev_err(&pdev->dev, "failed to request IRQ#%u: %d\n", mc->irq,
- err);
- return err;
+ irq = platform_get_irq(pdev, i);
+ if (irq < 0)
+ return irq;
+
+ err = devm_request_irq(&pdev->dev, irq, mc->soc->handle_irq[i], 0,
+ dev_name(&pdev->dev), mc);
+ if (err < 0) {
+ dev_err(&pdev->dev, "failed to request IRQ#%u: %d\n", irq, err);
+ return err;
+ }
+ }
+
+ for (i = 0; i < mc->soc->num_intmasks; i++) {
+ if (mc->soc->num_channels)
+ mc_ch_writel(mc, MC_BROADCAST_CHANNEL, mc->soc->intmasks[i].mask,
+ mc->soc->intmasks[i].reg);
+ else
+ mc_writel(mc, mc->soc->intmasks[i].mask, mc->soc->intmasks[i].reg);
}
}
@@ -971,8 +993,7 @@ static int tegra_mc_probe(struct platform_device *pdev)
if (IS_ENABLED(CONFIG_TEGRA_IOMMU_SMMU) && mc->soc->smmu) {
mc->smmu = tegra_smmu_probe(&pdev->dev, mc->soc->smmu, mc);
if (IS_ERR(mc->smmu)) {
- dev_err(&pdev->dev, "failed to probe SMMU: %ld\n",
- PTR_ERR(mc->smmu));
+ dev_err(&pdev->dev, "failed to probe SMMU: %pe\n", mc->smmu);
mc->smmu = NULL;
}
}
diff --git a/drivers/memory/tegra/mc.h b/drivers/memory/tegra/mc.h
index 1d97cf4d3a94..649b54369263 100644
--- a/drivers/memory/tegra/mc.h
+++ b/drivers/memory/tegra/mc.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
- * Copyright (C) 2014-2025 NVIDIA CORPORATION. All rights reserved.
+ * Copyright (C) 2014-2026 NVIDIA CORPORATION. All rights reserved.
*/
#ifndef MEMORY_TEGRA_MC_H
@@ -13,15 +13,36 @@
#include <soc/tegra/mc.h>
#define MC_INTSTATUS 0x00
+/* Bit field of MC_INTSTATUS register */
+#define MC_INT_DECERR_EMEM BIT(6)
+#define MC_INT_INVALID_GART_PAGE BIT(7)
+#define MC_INT_SECURITY_VIOLATION BIT(8)
+#define MC_INT_ARBITRATION_EMEM BIT(9)
+#define MC_INT_INVALID_SMMU_PAGE BIT(10)
+#define MC_INT_INVALID_APB_ASID_UPDATE BIT(11)
+#define MC_INT_DECERR_VPR BIT(12)
+#define MC_INT_SECERR_SEC BIT(13)
+#define MC_INT_DECERR_MTS BIT(16)
+#define MC_INT_DECERR_GENERALIZED_CARVEOUT BIT(17)
+#define MC_INT_DECERR_ROUTE_SANITY BIT(20)
+#define MC_INT_DECERR_ROUTE_SANITY_GIC_MSI BIT(21)
+
#define MC_INTMASK 0x04
-#define MC_ERR_STATUS 0x08
-#define MC_ERR_ADR 0x0c
#define MC_GART_ERROR_REQ 0x30
#define MC_EMEM_ADR_CFG 0x54
+#define MC_EMEM_ADR_CFG_EMEM_NUMDEV BIT(0)
+
#define MC_DECERR_EMEM_OTHERS_STATUS 0x58
#define MC_SECURITY_VIOLATION_STATUS 0x74
#define MC_EMEM_ARB_CFG 0x90
+#define MC_EMEM_ARB_CFG_CYCLES_PER_UPDATE(x) ((x) & 0x1ff)
+#define MC_EMEM_ARB_CFG_CYCLES_PER_UPDATE_MASK 0x1ff
+
#define MC_EMEM_ARB_OUTSTANDING_REQ 0x94
+#define MC_EMEM_ARB_OUTSTANDING_REQ_HOLDOFF_OVERRIDE BIT(30)
+#define MC_EMEM_ARB_OUTSTANDING_REQ_LIMIT_ENABLE BIT(31)
+#define MC_EMEM_ARB_OUTSTANDING_REQ_MAX_MASK 0x1ff
+
#define MC_EMEM_ARB_TIMING_RCD 0x98
#define MC_EMEM_ARB_TIMING_RP 0x9c
#define MC_EMEM_ARB_TIMING_RC 0xa0
@@ -41,60 +62,97 @@
#define MC_EMEM_ARB_MISC1 0xdc
#define MC_EMEM_ARB_RING1_THROTTLE 0xe0
#define MC_EMEM_ARB_OVERRIDE 0xe8
+#define MC_EMEM_ARB_OVERRIDE_EACK_MASK 0x3
+
#define MC_TIMING_CONTROL_DBG 0xf8
#define MC_TIMING_CONTROL 0xfc
-#define MC_ERR_VPR_STATUS 0x654
-#define MC_ERR_VPR_ADR 0x658
-#define MC_ERR_SEC_STATUS 0x67c
-#define MC_ERR_SEC_ADR 0x680
-#define MC_ERR_MTS_STATUS 0x9b0
-#define MC_ERR_MTS_ADR 0x9b4
-#define MC_ERR_ROUTE_SANITY_STATUS 0x9c0
-#define MC_ERR_ROUTE_SANITY_ADR 0x9c4
-#define MC_ERR_GENERALIZED_CARVEOUT_STATUS 0xc00
-#define MC_ERR_GENERALIZED_CARVEOUT_ADR 0xc04
-#define MC_EMEM_ADR_CFG_CHANNEL_ENABLE 0xdf8
-#define MC_GLOBAL_INTSTATUS 0xf24
-#define MC_ERR_ADR_HI 0x11fc
+#define MC_TIMING_UPDATE BIT(0)
-#define MC_INT_DECERR_ROUTE_SANITY BIT(20)
-#define MC_INT_DECERR_GENERALIZED_CARVEOUT BIT(17)
-#define MC_INT_DECERR_MTS BIT(16)
-#define MC_INT_SECERR_SEC BIT(13)
-#define MC_INT_DECERR_VPR BIT(12)
-#define MC_INT_INVALID_APB_ASID_UPDATE BIT(11)
-#define MC_INT_INVALID_SMMU_PAGE BIT(10)
-#define MC_INT_ARBITRATION_EMEM BIT(9)
-#define MC_INT_SECURITY_VIOLATION BIT(8)
-#define MC_INT_INVALID_GART_PAGE BIT(7)
-#define MC_INT_DECERR_EMEM BIT(6)
+#define MC_GLOBAL_INTSTATUS 0xf24
-#define MC_ERR_STATUS_TYPE_SHIFT 28
-#define MC_ERR_STATUS_TYPE_INVALID_SMMU_PAGE (0x6 << 28)
-#define MC_ERR_STATUS_TYPE_MASK (0x7 << 28)
-#define MC_ERR_STATUS_READABLE BIT(27)
-#define MC_ERR_STATUS_WRITABLE BIT(26)
-#define MC_ERR_STATUS_NONSECURE BIT(25)
-#define MC_ERR_STATUS_ADR_HI_SHIFT 20
-#define MC_ERR_STATUS_ADR_HI_MASK 0x3
-#define MC_ERR_STATUS_SECURITY BIT(17)
+/* Bit field of MC_ERR_STATUS_0 register */
#define MC_ERR_STATUS_RW BIT(16)
+#define MC_ERR_STATUS_SECURITY BIT(17)
+#define MC_ERR_STATUS_NONSECURE BIT(25)
+#define MC_ERR_STATUS_WRITABLE BIT(26)
+#define MC_ERR_STATUS_READABLE BIT(27)
-#define MC_EMEM_ADR_CFG_EMEM_NUMDEV BIT(0)
-
-#define MC_EMEM_ARB_CFG_CYCLES_PER_UPDATE(x) ((x) & 0x1ff)
-#define MC_EMEM_ARB_CFG_CYCLES_PER_UPDATE_MASK 0x1ff
-
-#define MC_EMEM_ARB_OUTSTANDING_REQ_MAX_MASK 0x1ff
-#define MC_EMEM_ARB_OUTSTANDING_REQ_HOLDOFF_OVERRIDE BIT(30)
-#define MC_EMEM_ARB_OUTSTANDING_REQ_LIMIT_ENABLE BIT(31)
+#define MC_ERR_STATUS_GSC_ADR_HI_MASK 0xffff
+#define MC_ERR_STATUS_GSC_ADR_HI_SHIFT 16
+#define MC_ERR_STATUS_RT_ADR_HI_SHIFT 15
-#define MC_EMEM_ARB_OVERRIDE_EACK_MASK 0x3
+#define MC_ERR_STATUS_TYPE_SHIFT 28
+#define MC_ERR_STATUS_TYPE_INVALID_SMMU_PAGE (0x6 << 28)
+#define MC_ERR_STATUS_RT_TYPE_MASK (0xf << 28)
+#define MC_ERR_STATUS_RT_TYPE_SHIFT 28
-#define MC_TIMING_UPDATE BIT(0)
+#define MC_ERR_STATUS_ADR_HI_SHIFT 20
#define MC_BROADCAST_CHANNEL ~0
+/* Tegra264 specific registers */
+
+/* Registers for MSS HUB */
+#define MSS_HUB_GLOBAL_INTSTATUS_0 0x6000
+#define MSS_HUBC_INTR BIT(0)
+#define MSS_HUB_GLOBAL_MASK 0x7F00
+#define MSS_HUB_GLOBAL_SHIFT 8
+
+#define MSS_HUB_HUBC_INTSTATUS_0 0x6008
+#define MSS_HUB_INTRSTATUS_0 0x600c
+#define MSS_HUB_HUBC_INTMASK_0 0x6010
+#define MSS_HUB_HUBC_SCRUB_DONE_INTMASK BIT(0)
+
+#define MSS_HUB_HUBC_INTPRIORITY_0 0x6014
+#define MSS_HUB_INTRMASK_0 0x6018
+#define MSS_HUB_COALESCER_ERR_INTMASK BIT(0)
+#define MSS_HUB_SMMU_BYPASS_ALLOW_ERR_INTMASK BIT(1)
+#define MSS_HUB_ILLEGAL_TBUGRP_ID_INTMASK BIT(2)
+#define MSS_HUB_MSI_ERR_INTMASK BIT(3)
+#define MSS_HUB_POISON_RSP_INTMASK BIT(4)
+#define MSS_HUB_RESTRICTED_ACCESS_ERR_INTMASK BIT(5)
+#define MSS_HUB_RESERVED_PA_ERR_INTMASK BIT(6)
+
+#define MSS_HUB_INTRPRIORITY_0 0x601c
+#define MSS_HUB_SMMU_BYPASS_ALLOW_ERR_STATUS_0 0x6020
+#define MSS_HUB_MSI_ERR_STATUS_0 0x6024
+#define MSS_HUB_POISON_RSP_STATUS_0 0x6028
+#define MSS_HUB_COALESCE_ERR_STATUS_0 0x60e0
+#define MSS_HUB_COALESCE_ERR_ADR_HI_0 0x60e4
+#define MSS_HUB_COALESCE_ERR_ADR_0 0x60e8
+#define MSS_HUB_RESTRICTED_ACCESS_ERR_STATUS_0 0x638c
+#define MSS_HUB_RESERVED_PA_ERR_STATUS_0 0x6390
+#define MSS_HUB_ILLEGAL_TBUGRP_ID_ERR_STATUS_0 0x63b0
+
+/* Registers for channels */
+#define MC_CH_INTSTATUS_0 0x82d4
+#define MC_CH_INTMASK_0 0x82d8
+#define WCAM_ERR_INTMASK BIT(19)
+
+#define MC_ERR_GENERALIZED_CARVEOUT_STATUS_1_0 0xbc74
+
+/* Registers for MCF */
+#define MCF_COMMON_INTSTATUS0_0_0 0xce04
+#define MCF_INTSTATUS_0 0xce2c
+#define MCF_INTMASK_0 0xce30
+#define MCF_INTPRIORITY_0 0xce34
+
+/* Registers for SBS */
+#define MSS_SBS_INTSTATUS_0 0xec08
+#define MSS_SBS_INTMASK_0 0xec0c
+#define MSS_SBS_FILL_FIFO_ISO_OVERFLOW_INTMASK BIT(0)
+#define MSS_SBS_FILL_FIFO_SISO_OVERFLOW_INTMASK BIT(1)
+#define MSS_SBS_FILL_FIFO_NISO_OVERFLOW_INTMASK BIT(2)
+
+/* Bit field of MC_ERR_ROUTE_SANITY_STATUS_0 register */
+#define MC_ERR_ROUTE_SANITY_RW BIT(12)
+#define MC_ERR_ROUTE_SANITY_SEC BIT(13)
+
+#define ERR_GENERALIZED_APERTURE_ID_SHIFT 0
+#define ERR_GENERALIZED_APERTURE_ID_MASK 0x1F
+#define ERR_GENERALIZED_CARVEOUT_APERTURE_ID_SHIFT 5
+#define ERR_GENERALIZED_CARVEOUT_APERTURE_ID_MASK 0x1F
+
static inline u32 tegra_mc_scale_percents(u64 val, unsigned int percents)
{
val = val * percents;
@@ -203,8 +261,9 @@ extern const struct tegra_mc_ops tegra186_mc_ops;
#endif
irqreturn_t tegra30_mc_handle_irq(int irq, void *data);
+extern const irq_handler_t tegra30_mc_irq_handlers[1];
extern const char * const tegra_mc_status_names[32];
-extern const char * const tegra_mc_error_names[8];
+extern const char * const tegra20_mc_error_names[8];
/*
* These IDs are for internal use of Tegra ICC drivers. The ID numbers are
diff --git a/drivers/memory/tegra/tegra114.c b/drivers/memory/tegra/tegra114.c
index 41350570c815..02dd4e26288a 100644
--- a/drivers/memory/tegra/tegra114.c
+++ b/drivers/memory/tegra/tegra114.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
- * Copyright (C) 2014 NVIDIA CORPORATION. All rights reserved.
+ * Copyright (C) 2014-2026 NVIDIA CORPORATION. All rights reserved.
*/
#include <linux/of.h>
@@ -1101,6 +1101,14 @@ static const struct tegra_mc_reset tegra114_mc_resets[] = {
TEGRA114_MC_RESET(VI, 0x200, 0x204, 17),
};
+static const struct tegra_mc_intmask tegra114_mc_intmasks[] = {
+ {
+ .reg = MC_INTMASK,
+ .mask = MC_INT_INVALID_SMMU_PAGE | MC_INT_SECURITY_VIOLATION |
+ MC_INT_DECERR_EMEM,
+ },
+};
+
const struct tegra_mc_soc tegra114_mc_soc = {
.clients = tegra114_mc_clients,
.num_clients = ARRAY_SIZE(tegra114_mc_clients),
@@ -1108,10 +1116,14 @@ const struct tegra_mc_soc tegra114_mc_soc = {
.atom_size = 32,
.client_id_mask = 0x7f,
.smmu = &tegra114_smmu_soc,
- .intmask = MC_INT_INVALID_SMMU_PAGE | MC_INT_SECURITY_VIOLATION |
- MC_INT_DECERR_EMEM,
+ .intmasks = tegra114_mc_intmasks,
+ .num_intmasks = ARRAY_SIZE(tegra114_mc_intmasks),
.reset_ops = &tegra_mc_reset_ops_common,
.resets = tegra114_mc_resets,
.num_resets = ARRAY_SIZE(tegra114_mc_resets),
.ops = &tegra30_mc_ops,
+ .regs = &tegra20_mc_regs,
+ .handle_irq = tegra30_mc_irq_handlers,
+ .num_interrupts = ARRAY_SIZE(tegra30_mc_irq_handlers),
+ .mc_err_status_type_mask = (0x7 << 28),
};
diff --git a/drivers/memory/tegra/tegra124-emc.c b/drivers/memory/tegra/tegra124-emc.c
index ff26815e51f1..5cfbc169c5f9 100644
--- a/drivers/memory/tegra/tegra124-emc.c
+++ b/drivers/memory/tegra/tegra124-emc.c
@@ -608,7 +608,7 @@ static int tegra124_emc_prepare_timing_change(struct tegra_emc *emc,
if ((last->emc_mode_1 & 0x1) == (timing->emc_mode_1 & 0x1))
dll_change = DLL_CHANGE_NONE;
- else if (timing->emc_mode_1 & 0x1)
+ else if (!(timing->emc_mode_1 & 0x1))
dll_change = DLL_CHANGE_ON;
else
dll_change = DLL_CHANGE_OFF;
diff --git a/drivers/memory/tegra/tegra124.c b/drivers/memory/tegra/tegra124.c
index 991d4f7bc070..df87c5038625 100644
--- a/drivers/memory/tegra/tegra124.c
+++ b/drivers/memory/tegra/tegra124.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
- * Copyright (C) 2014 NVIDIA CORPORATION. All rights reserved.
+ * Copyright (C) 2014-2026 NVIDIA CORPORATION. All rights reserved.
*/
#include <linux/of.h>
@@ -1258,6 +1258,15 @@ static const struct tegra_smmu_soc tegra124_smmu_soc = {
.num_asids = 128,
};
+static const struct tegra_mc_intmask tegra124_mc_intmasks[] = {
+ {
+ .reg = MC_INTMASK,
+ .mask = MC_INT_DECERR_MTS | MC_INT_SECERR_SEC | MC_INT_DECERR_VPR |
+ MC_INT_INVALID_APB_ASID_UPDATE | MC_INT_INVALID_SMMU_PAGE |
+ MC_INT_SECURITY_VIOLATION | MC_INT_DECERR_EMEM,
+ },
+};
+
const struct tegra_mc_soc tegra124_mc_soc = {
.clients = tegra124_mc_clients,
.num_clients = ARRAY_SIZE(tegra124_mc_clients),
@@ -1267,14 +1276,18 @@ const struct tegra_mc_soc tegra124_mc_soc = {
.smmu = &tegra124_smmu_soc,
.emem_regs = tegra124_mc_emem_regs,
.num_emem_regs = ARRAY_SIZE(tegra124_mc_emem_regs),
- .intmask = MC_INT_DECERR_MTS | MC_INT_SECERR_SEC | MC_INT_DECERR_VPR |
- MC_INT_INVALID_APB_ASID_UPDATE | MC_INT_INVALID_SMMU_PAGE |
- MC_INT_SECURITY_VIOLATION | MC_INT_DECERR_EMEM,
+ .intmasks = tegra124_mc_intmasks,
+ .num_intmasks = ARRAY_SIZE(tegra124_mc_intmasks),
.reset_ops = &tegra_mc_reset_ops_common,
.resets = tegra124_mc_resets,
.num_resets = ARRAY_SIZE(tegra124_mc_resets),
.icc_ops = &tegra124_mc_icc_ops,
.ops = &tegra30_mc_ops,
+ .regs = &tegra20_mc_regs,
+ .handle_irq = tegra30_mc_irq_handlers,
+ .num_interrupts = ARRAY_SIZE(tegra30_mc_irq_handlers),
+ .mc_addr_hi_mask = 0x3,
+ .mc_err_status_type_mask = (0x7 << 28),
};
#endif /* CONFIG_ARCH_TEGRA_124_SOC */
@@ -1292,6 +1305,15 @@ static const struct tegra_smmu_soc tegra132_smmu_soc = {
.num_asids = 128,
};
+static const struct tegra_mc_intmask tegra132_mc_intmasks[] = {
+ {
+ .reg = MC_INTMASK,
+ .mask = MC_INT_DECERR_MTS | MC_INT_SECERR_SEC | MC_INT_DECERR_VPR |
+ MC_INT_INVALID_APB_ASID_UPDATE | MC_INT_INVALID_SMMU_PAGE |
+ MC_INT_SECURITY_VIOLATION | MC_INT_DECERR_EMEM,
+ },
+};
+
const struct tegra_mc_soc tegra132_mc_soc = {
.clients = tegra124_mc_clients,
.num_clients = ARRAY_SIZE(tegra124_mc_clients),
@@ -1299,13 +1321,17 @@ const struct tegra_mc_soc tegra132_mc_soc = {
.atom_size = 32,
.client_id_mask = 0x7f,
.smmu = &tegra132_smmu_soc,
- .intmask = MC_INT_DECERR_MTS | MC_INT_SECERR_SEC | MC_INT_DECERR_VPR |
- MC_INT_INVALID_APB_ASID_UPDATE | MC_INT_INVALID_SMMU_PAGE |
- MC_INT_SECURITY_VIOLATION | MC_INT_DECERR_EMEM,
+ .intmasks = tegra132_mc_intmasks,
+ .num_intmasks = ARRAY_SIZE(tegra132_mc_intmasks),
.reset_ops = &tegra_mc_reset_ops_common,
.resets = tegra124_mc_resets,
.num_resets = ARRAY_SIZE(tegra124_mc_resets),
.icc_ops = &tegra124_mc_icc_ops,
.ops = &tegra30_mc_ops,
+ .regs = &tegra20_mc_regs,
+ .handle_irq = tegra30_mc_irq_handlers,
+ .num_interrupts = ARRAY_SIZE(tegra30_mc_irq_handlers),
+ .mc_addr_hi_mask = 0x3,
+ .mc_err_status_type_mask = (0x7 << 28),
};
#endif /* CONFIG_ARCH_TEGRA_132_SOC */
diff --git a/drivers/memory/tegra/tegra186-emc.c b/drivers/memory/tegra/tegra186-emc.c
index dfddceecdd1a..03ebab6fbe68 100644
--- a/drivers/memory/tegra/tegra186-emc.c
+++ b/drivers/memory/tegra/tegra186-emc.c
@@ -22,6 +22,7 @@ struct tegra186_emc {
struct tegra_bpmp *bpmp;
struct device *dev;
struct clk *clk;
+ struct clk *clk_dbb;
struct tegra186_emc_dvfs *dvfs;
unsigned int num_dvfs;
@@ -328,6 +329,13 @@ static int tegra186_emc_probe(struct platform_device *pdev)
goto put_bpmp;
}
+ emc->clk_dbb = devm_clk_get_optional_enabled(&pdev->dev, "dbb");
+ if (IS_ERR(emc->clk_dbb)) {
+ err = dev_err_probe(&pdev->dev, PTR_ERR(emc->clk_dbb),
+ "failed to get DBB clock\n");
+ goto put_bpmp;
+ }
+
platform_set_drvdata(pdev, emc);
emc->dev = &pdev->dev;
diff --git a/drivers/memory/tegra/tegra186.c b/drivers/memory/tegra/tegra186.c
index aee11457bf8e..91d56165605f 100644
--- a/drivers/memory/tegra/tegra186.c
+++ b/drivers/memory/tegra/tegra186.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
- * Copyright (C) 2017-2025 NVIDIA CORPORATION. All rights reserved.
+ * Copyright (C) 2017-2026 NVIDIA CORPORATION. All rights reserved.
*/
#include <linux/io.h>
@@ -174,7 +174,6 @@ const struct tegra_mc_ops tegra186_mc_ops = {
.remove = tegra186_mc_remove,
.resume = tegra186_mc_resume,
.probe_device = tegra186_mc_probe_device,
- .handle_irq = tegra30_mc_handle_irq,
};
#if defined(CONFIG_ARCH_TEGRA_186_SOC)
@@ -902,17 +901,30 @@ static const struct tegra_mc_client tegra186_mc_clients[] = {
},
};
+static const struct tegra_mc_intmask tegra186_mc_intmasks[] = {
+ {
+ .reg = MC_INTMASK,
+ .mask = MC_INT_DECERR_GENERALIZED_CARVEOUT | MC_INT_DECERR_MTS |
+ MC_INT_SECERR_SEC | MC_INT_DECERR_VPR |
+ MC_INT_SECURITY_VIOLATION | MC_INT_DECERR_EMEM,
+ },
+};
+
const struct tegra_mc_soc tegra186_mc_soc = {
.num_clients = ARRAY_SIZE(tegra186_mc_clients),
.clients = tegra186_mc_clients,
.num_address_bits = 40,
.num_channels = 4,
.client_id_mask = 0xff,
- .intmask = MC_INT_DECERR_GENERALIZED_CARVEOUT | MC_INT_DECERR_MTS |
- MC_INT_SECERR_SEC | MC_INT_DECERR_VPR |
- MC_INT_SECURITY_VIOLATION | MC_INT_DECERR_EMEM,
+ .intmasks = tegra186_mc_intmasks,
+ .num_intmasks = ARRAY_SIZE(tegra186_mc_intmasks),
.ops = &tegra186_mc_ops,
.ch_intmask = 0x0000000f,
.global_intstatus_channel_shift = 0,
+ .regs = &tegra20_mc_regs,
+ .handle_irq = tegra30_mc_irq_handlers,
+ .num_interrupts = ARRAY_SIZE(tegra30_mc_irq_handlers),
+ .mc_addr_hi_mask = 0x3,
+ .mc_err_status_type_mask = (0x7 << 28),
};
#endif
diff --git a/drivers/memory/tegra/tegra194.c b/drivers/memory/tegra/tegra194.c
index 26035ac3a1eb..a8cc57690696 100644
--- a/drivers/memory/tegra/tegra194.c
+++ b/drivers/memory/tegra/tegra194.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
- * Copyright (C) 2017-2021 NVIDIA CORPORATION. All rights reserved.
+ * Copyright (C) 2017-2026 NVIDIA CORPORATION. All rights reserved.
*/
#include <soc/tegra/mc.h>
@@ -1343,19 +1343,31 @@ static const struct tegra_mc_client tegra194_mc_clients[] = {
},
};
+static const struct tegra_mc_intmask tegra194_mc_intmasks[] = {
+ {
+ .reg = MC_INTMASK,
+ .mask = MC_INT_DECERR_ROUTE_SANITY | MC_INT_DECERR_GENERALIZED_CARVEOUT |
+ MC_INT_DECERR_MTS | MC_INT_SECERR_SEC | MC_INT_DECERR_VPR |
+ MC_INT_SECURITY_VIOLATION | MC_INT_DECERR_EMEM,
+ },
+};
+
const struct tegra_mc_soc tegra194_mc_soc = {
.num_clients = ARRAY_SIZE(tegra194_mc_clients),
.clients = tegra194_mc_clients,
.num_address_bits = 40,
.num_channels = 16,
.client_id_mask = 0xff,
- .intmask = MC_INT_DECERR_ROUTE_SANITY |
- MC_INT_DECERR_GENERALIZED_CARVEOUT | MC_INT_DECERR_MTS |
- MC_INT_SECERR_SEC | MC_INT_DECERR_VPR |
- MC_INT_SECURITY_VIOLATION | MC_INT_DECERR_EMEM,
+ .intmasks = tegra194_mc_intmasks,
+ .num_intmasks = ARRAY_SIZE(tegra194_mc_intmasks),
.has_addr_hi_reg = true,
.ops = &tegra186_mc_ops,
.icc_ops = &tegra_mc_icc_ops,
.ch_intmask = 0x00000f00,
.global_intstatus_channel_shift = 8,
+ .regs = &tegra20_mc_regs,
+ .handle_irq = tegra30_mc_irq_handlers,
+ .num_interrupts = ARRAY_SIZE(tegra30_mc_irq_handlers),
+ .mc_addr_hi_mask = 0x3,
+ .mc_err_status_type_mask = (0x7 << 28),
};
diff --git a/drivers/memory/tegra/tegra20.c b/drivers/memory/tegra/tegra20.c
index 4748113bfe9d..27dd6886f86e 100644
--- a/drivers/memory/tegra/tegra20.c
+++ b/drivers/memory/tegra/tegra20.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
- * Copyright (C) 2012 NVIDIA CORPORATION. All rights reserved.
+ * Copyright (C) 2012-2026 NVIDIA CORPORATION. All rights reserved.
*/
#include <linux/bitfield.h>
@@ -695,7 +695,7 @@ static irqreturn_t tegra20_mc_handle_irq(int irq, void *data)
unsigned int bit;
/* mask all interrupts to avoid flooding */
- status = mc_readl(mc, MC_INTSTATUS) & mc->soc->intmask;
+ status = mc_readl(mc, MC_INTSTATUS) & mc->soc->intmasks[0].mask;
if (!status)
return IRQ_NONE;
@@ -713,7 +713,7 @@ static irqreturn_t tegra20_mc_handle_irq(int irq, void *data)
value = mc_readl(mc, reg);
id = value & mc->soc->client_id_mask;
- desc = tegra_mc_error_names[2];
+ desc = tegra20_mc_error_names[2];
if (value & BIT(31))
direction = "write";
@@ -724,7 +724,7 @@ static irqreturn_t tegra20_mc_handle_irq(int irq, void *data)
value = mc_readl(mc, reg);
id = (value >> 1) & mc->soc->client_id_mask;
- desc = tegra_mc_error_names[2];
+ desc = tegra20_mc_error_names[2];
if (value & BIT(0))
direction = "write";
@@ -736,7 +736,7 @@ static irqreturn_t tegra20_mc_handle_irq(int irq, void *data)
id = value & mc->soc->client_id_mask;
type = (value & BIT(30)) ? 4 : 3;
- desc = tegra_mc_error_names[type];
+ desc = tegra20_mc_error_names[type];
secure = "secure ";
if (value & BIT(31))
@@ -761,9 +761,20 @@ static irqreturn_t tegra20_mc_handle_irq(int irq, void *data)
return IRQ_HANDLED;
}
+static const irq_handler_t tegra20_mc_irq_handlers[] = {
+ tegra20_mc_handle_irq
+};
+
static const struct tegra_mc_ops tegra20_mc_ops = {
.probe = tegra20_mc_probe,
- .handle_irq = tegra20_mc_handle_irq,
+};
+
+static const struct tegra_mc_intmask tegra20_mc_intmasks[] = {
+ {
+ .reg = MC_INTMASK,
+ .mask = MC_INT_SECURITY_VIOLATION | MC_INT_INVALID_GART_PAGE |
+ MC_INT_DECERR_EMEM,
+ },
};
const struct tegra_mc_soc tegra20_mc_soc = {
@@ -771,11 +782,15 @@ const struct tegra_mc_soc tegra20_mc_soc = {
.num_clients = ARRAY_SIZE(tegra20_mc_clients),
.num_address_bits = 32,
.client_id_mask = 0x3f,
- .intmask = MC_INT_SECURITY_VIOLATION | MC_INT_INVALID_GART_PAGE |
- MC_INT_DECERR_EMEM,
+ .intmasks = tegra20_mc_intmasks,
+ .num_intmasks = ARRAY_SIZE(tegra20_mc_intmasks),
.reset_ops = &tegra20_mc_reset_ops,
.resets = tegra20_mc_resets,
.num_resets = ARRAY_SIZE(tegra20_mc_resets),
.icc_ops = &tegra20_mc_icc_ops,
.ops = &tegra20_mc_ops,
+ .regs = &tegra20_mc_regs,
+ .handle_irq = tegra20_mc_irq_handlers,
+ .num_interrupts = ARRAY_SIZE(tegra20_mc_irq_handlers),
+ .mc_err_status_type_mask = (0x7 << 28),
};
diff --git a/drivers/memory/tegra/tegra210.c b/drivers/memory/tegra/tegra210.c
index 3c2949c16fde..f58f3ef6f681 100644
--- a/drivers/memory/tegra/tegra210.c
+++ b/drivers/memory/tegra/tegra210.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
- * Copyright (C) 2015 NVIDIA CORPORATION. All rights reserved.
+ * Copyright (C) 2015-2026 NVIDIA CORPORATION. All rights reserved.
*/
#include <dt-bindings/memory/tegra210-mc.h>
@@ -1273,6 +1273,15 @@ static const struct tegra_mc_reset tegra210_mc_resets[] = {
TEGRA210_MC_RESET(TSECB, 0x970, 0x974, 13),
};
+static const struct tegra_mc_intmask tegra210_mc_intmasks[] = {
+ {
+ .reg = MC_INTMASK,
+ .mask = MC_INT_DECERR_MTS | MC_INT_SECERR_SEC | MC_INT_DECERR_VPR |
+ MC_INT_INVALID_APB_ASID_UPDATE | MC_INT_INVALID_SMMU_PAGE |
+ MC_INT_SECURITY_VIOLATION | MC_INT_DECERR_EMEM,
+ },
+};
+
const struct tegra_mc_soc tegra210_mc_soc = {
.clients = tegra210_mc_clients,
.num_clients = ARRAY_SIZE(tegra210_mc_clients),
@@ -1280,11 +1289,15 @@ const struct tegra_mc_soc tegra210_mc_soc = {
.atom_size = 64,
.client_id_mask = 0xff,
.smmu = &tegra210_smmu_soc,
- .intmask = MC_INT_DECERR_MTS | MC_INT_SECERR_SEC | MC_INT_DECERR_VPR |
- MC_INT_INVALID_APB_ASID_UPDATE | MC_INT_INVALID_SMMU_PAGE |
- MC_INT_SECURITY_VIOLATION | MC_INT_DECERR_EMEM,
+ .intmasks = tegra210_mc_intmasks,
+ .num_intmasks = ARRAY_SIZE(tegra210_mc_intmasks),
.reset_ops = &tegra_mc_reset_ops_common,
.resets = tegra210_mc_resets,
.num_resets = ARRAY_SIZE(tegra210_mc_resets),
.ops = &tegra30_mc_ops,
+ .regs = &tegra20_mc_regs,
+ .handle_irq = tegra30_mc_irq_handlers,
+ .num_interrupts = ARRAY_SIZE(tegra30_mc_irq_handlers),
+ .mc_addr_hi_mask = 0x3,
+ .mc_err_status_type_mask = (0x7 << 28),
};
diff --git a/drivers/memory/tegra/tegra234.c b/drivers/memory/tegra/tegra234.c
index 5f57cea48b62..87b22038a5fb 100644
--- a/drivers/memory/tegra/tegra234.c
+++ b/drivers/memory/tegra/tegra234.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
- * Copyright (C) 2022-2023, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (C) 2022-2026, NVIDIA CORPORATION. All rights reserved.
*/
#include <soc/tegra/mc.h>
@@ -1132,16 +1132,23 @@ static const struct tegra_mc_icc_ops tegra234_mc_icc_ops = {
.set = tegra234_mc_icc_set,
};
+static const struct tegra_mc_intmask tegra234_mc_intmasks[] = {
+ {
+ .reg = MC_INTMASK,
+ .mask = MC_INT_DECERR_ROUTE_SANITY | MC_INT_DECERR_GENERALIZED_CARVEOUT |
+ MC_INT_DECERR_MTS | MC_INT_SECERR_SEC | MC_INT_DECERR_VPR |
+ MC_INT_SECURITY_VIOLATION | MC_INT_DECERR_EMEM,
+ },
+};
+
const struct tegra_mc_soc tegra234_mc_soc = {
.num_clients = ARRAY_SIZE(tegra234_mc_clients),
.clients = tegra234_mc_clients,
.num_address_bits = 40,
.num_channels = 16,
.client_id_mask = 0x1ff,
- .intmask = MC_INT_DECERR_ROUTE_SANITY |
- MC_INT_DECERR_GENERALIZED_CARVEOUT | MC_INT_DECERR_MTS |
- MC_INT_SECERR_SEC | MC_INT_DECERR_VPR |
- MC_INT_SECURITY_VIOLATION | MC_INT_DECERR_EMEM,
+ .intmasks = tegra234_mc_intmasks,
+ .num_intmasks = ARRAY_SIZE(tegra234_mc_intmasks),
.has_addr_hi_reg = true,
.ops = &tegra186_mc_ops,
.icc_ops = &tegra234_mc_icc_ops,
@@ -1152,4 +1159,9 @@ const struct tegra_mc_soc tegra234_mc_soc = {
* supported.
*/
.num_carveouts = 32,
+ .regs = &tegra20_mc_regs,
+ .handle_irq = tegra30_mc_irq_handlers,
+ .num_interrupts = ARRAY_SIZE(tegra30_mc_irq_handlers),
+ .mc_addr_hi_mask = 0x3,
+ .mc_err_status_type_mask = (0x7 << 28),
};
diff --git a/drivers/memory/tegra/tegra264.c b/drivers/memory/tegra/tegra264.c
index 5203e6c11372..e43ef14da1ee 100644
--- a/drivers/memory/tegra/tegra264.c
+++ b/drivers/memory/tegra/tegra264.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
- * Copyright (C) 2025, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (C) 2025-2026, NVIDIA CORPORATION. All rights reserved.
*/
#include <dt-bindings/memory/nvidia,tegra264.h>
@@ -188,6 +188,41 @@ static const struct tegra_mc_client tegra264_mc_clients[] = {
},
};
+static const char *const tegra264_hub_error_names[32] = {
+ [0] = "coalescer error",
+ [1] = "SMMU BYPASS ALLOW error",
+ [2] = "Illegal tbugrp_id error",
+ [3] = "Malformed MSI request error",
+ [4] = "Read response with poison bit error",
+ [5] = "Restricted access violation error",
+ [6] = "Reserved PA error",
+};
+
+static const char *const tegra264_mc_error_names[4] = {
+ [1] = "EMEM decode error",
+ [2] = "TrustZone violation",
+ [3] = "Carveout violation",
+};
+
+static const char *const tegra264_rt_error_names[16] = {
+ [1] = "DECERR_PARTIAL_POPULATED",
+ [2] = "DECERR_SMMU_BYPASS",
+ [3] = "DECERR_INVALID_MMIO",
+ [4] = "DECERR_INVALID_GIC_MSI",
+ [5] = "DECERR_ATOMIC_SYSRAM",
+ [9] = "DECERR_REMOTE_REQ_PRE_BOOT",
+ [10] = "DECERR_ISO_OVER_C2C",
+ [11] = "DECERR_UNSUPPORTED_SBS_OPCODE",
+ [12] = "DECERR_SBS_REQ_OVER_SISO_LL",
+};
+
+/*
+ * MC instance aperture mapping for hubc registers
+ */
+static const int mc_hubc_aperture_number[5] = {
+ 7, 8, 9, 10, 11
+};
+
/*
* tegra264_mc_icc_set() - Pass MC client info to the BPMP-FW
* @src: ICC node for Memory Controller's (MC) Client
@@ -283,6 +318,312 @@ static int tegra264_mc_icc_get_init_bw(struct icc_node *node, u32 *avg, u32 *pea
return 0;
}
+static void mcf_log_fault(struct tegra_mc *mc, u32 channel, unsigned long mcf_ch_intstatus)
+{
+ unsigned int bit;
+
+ for_each_set_bit(bit, &mcf_ch_intstatus, 32) {
+ const char *client = "unknown", *desc = "NA";
+ u32 status_reg, status1_reg = 0, addr_reg, addr_hi_reg = 0, err_type_mask = 0;
+ u32 value, client_id, i, addr_hi_shift = 0, addr_hi_mask = 0, status1;
+ u32 mc_rw_bit = MC_ERR_STATUS_RW, mc_sec_bit = MC_ERR_STATUS_SECURITY;
+ phys_addr_t addr = 0;
+ u8 type;
+
+ switch (BIT(bit)) {
+ case MC_INT_DECERR_EMEM:
+ case MC_INT_SECURITY_VIOLATION:
+ status_reg = mc->soc->regs->err_status;
+ addr_reg = mc->soc->regs->err_add;
+ addr_hi_reg = mc->soc->regs->err_add_hi;
+ err_type_mask = mc->soc->mc_err_status_type_mask;
+ break;
+
+ case MC_INT_DECERR_VPR:
+ status_reg = mc->soc->regs->err_vpr_status;
+ addr_reg = mc->soc->regs->err_vpr_add;
+ addr_hi_shift = MC_ERR_STATUS_ADR_HI_SHIFT;
+ addr_hi_mask = mc->soc->mc_addr_hi_mask;
+ break;
+
+ case MC_INT_SECERR_SEC:
+ status_reg = mc->soc->regs->err_sec_status;
+ addr_reg = mc->soc->regs->err_sec_add;
+ addr_hi_shift = MC_ERR_STATUS_ADR_HI_SHIFT;
+ addr_hi_mask = mc->soc->mc_addr_hi_mask;
+ break;
+
+ case MC_INT_DECERR_MTS:
+ status_reg = mc->soc->regs->err_mts_status;
+ addr_reg = mc->soc->regs->err_mts_add;
+ addr_hi_shift = MC_ERR_STATUS_ADR_HI_SHIFT;
+ addr_hi_mask = mc->soc->mc_addr_hi_mask;
+ break;
+
+ case MC_INT_DECERR_GENERALIZED_CARVEOUT:
+ status_reg = mc->soc->regs->err_gen_co_status;
+ status1_reg = MC_ERR_GENERALIZED_CARVEOUT_STATUS_1_0;
+ addr_reg = mc->soc->regs->err_gen_co_add;
+ addr_hi_shift = MC_ERR_STATUS_GSC_ADR_HI_SHIFT;
+ addr_hi_mask = MC_ERR_STATUS_GSC_ADR_HI_MASK;
+ break;
+
+ case MC_INT_DECERR_ROUTE_SANITY:
+ case MC_INT_DECERR_ROUTE_SANITY_GIC_MSI:
+ status_reg = mc->soc->regs->err_route_status;
+ addr_reg = mc->soc->regs->err_route_add;
+ addr_hi_shift = MC_ERR_STATUS_RT_ADR_HI_SHIFT;
+ addr_hi_mask = mc->soc->mc_addr_hi_mask;
+ mc_sec_bit = MC_ERR_ROUTE_SANITY_SEC;
+ mc_rw_bit = MC_ERR_ROUTE_SANITY_RW;
+ err_type_mask = MC_ERR_STATUS_RT_TYPE_MASK;
+ break;
+
+ default:
+ dev_err_ratelimited(mc->dev, "Incorrect MC interrupt mask\n");
+ return;
+ }
+
+ value = mc_ch_readl(mc, channel, status_reg);
+ if (addr_hi_reg) {
+ addr = mc_ch_readl(mc, channel, addr_hi_reg);
+ } else {
+ if (!status1_reg) {
+ addr = ((value >> addr_hi_shift) & addr_hi_mask);
+ } else {
+ status1 = mc_ch_readl(mc, channel, status1_reg);
+ addr = ((status1 >> addr_hi_shift) & addr_hi_mask);
+ }
+ }
+
+ addr <<= 32;
+ addr |= mc_ch_readl(mc, channel, addr_reg);
+
+ client_id = value & mc->soc->client_id_mask;
+ for (i = 0; i < mc->soc->num_clients; i++) {
+ if (mc->soc->clients[i].id == client_id) {
+ client = mc->soc->clients[i].name;
+ break;
+ }
+ }
+
+ if (err_type_mask == MC_ERR_STATUS_RT_TYPE_MASK) {
+ type = (value & err_type_mask) >>
+ MC_ERR_STATUS_RT_TYPE_SHIFT;
+ desc = tegra264_rt_error_names[type];
+ } else if (err_type_mask) {
+ type = (value & err_type_mask) >>
+ MC_ERR_STATUS_TYPE_SHIFT;
+ desc = tegra264_mc_error_names[type];
+ }
+
+ dev_err_ratelimited(mc->dev, "%s: %s %s @%pa: %s (%s)\n",
+ client, value & mc_sec_bit ? "secure" : "non-secure",
+ value & mc_rw_bit ? "write" : "read", &addr,
+ tegra_mc_status_names[bit] ?: "unknown", desc);
+ if (status1_reg)
+ dev_err_ratelimited(mc->dev, "gsc_apr_id=%u gsc_co_apr_id=%u\n",
+ ((status1 >> ERR_GENERALIZED_APERTURE_ID_SHIFT)
+ & ERR_GENERALIZED_APERTURE_ID_MASK),
+ ((status1 >> ERR_GENERALIZED_CARVEOUT_APERTURE_ID_SHIFT)
+ & ERR_GENERALIZED_CARVEOUT_APERTURE_ID_MASK));
+ }
+
+ /* clear interrupts */
+ mc_ch_writel(mc, channel, mcf_ch_intstatus, MCF_INTSTATUS_0);
+}
+
+static irqreturn_t handle_mcf_irq(int irq, void *data)
+{
+ struct tegra_mc *mc = data;
+ unsigned long common_intstat, intstatus;
+ u32 slice;
+
+ /* Read MCF_COMMON_INTSTATUS0_0_0 from MCB block */
+ common_intstat = mc_ch_readl(mc, MC_BROADCAST_CHANNEL, MCF_COMMON_INTSTATUS0_0_0);
+ if (common_intstat == 0) {
+ dev_warn(mc->dev, "No interrupt in MCF\n");
+ return IRQ_NONE;
+ }
+
+ for_each_set_bit(slice, &common_intstat, 32) {
+ /* Find out the slice number on which interrupt occurred */
+ if (slice > 4) {
+ dev_err(mc->dev, "Slice index out of bounds: %u\n", slice);
+ return IRQ_NONE;
+ }
+
+ intstatus = mc_ch_readl(mc, slice, MCF_INTSTATUS_0);
+ if (intstatus != 0)
+ mcf_log_fault(mc, slice, intstatus);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static void hub_log_fault(struct tegra_mc *mc, u32 hub, unsigned long hub_intstat)
+{
+ unsigned int bit;
+
+ for_each_set_bit(bit, &hub_intstat, 32) {
+ const char *client = "unknown";
+ u32 client_id, status_reg, value, i;
+ phys_addr_t addr = 0;
+
+ switch (BIT(bit)) {
+ case MSS_HUB_COALESCER_ERR_INTMASK:
+ status_reg = MSS_HUB_COALESCE_ERR_STATUS_0;
+ addr = mc_ch_readl(mc, hub, MSS_HUB_COALESCE_ERR_ADR_HI_0);
+ addr <<= 32;
+ addr |= mc_ch_readl(mc, hub, MSS_HUB_COALESCE_ERR_ADR_0);
+ break;
+
+ case MSS_HUB_SMMU_BYPASS_ALLOW_ERR_INTMASK:
+ status_reg = MSS_HUB_SMMU_BYPASS_ALLOW_ERR_STATUS_0;
+ break;
+
+ case MSS_HUB_ILLEGAL_TBUGRP_ID_INTMASK:
+ status_reg = MSS_HUB_ILLEGAL_TBUGRP_ID_ERR_STATUS_0;
+ break;
+
+ case MSS_HUB_MSI_ERR_INTMASK:
+ status_reg = MSS_HUB_MSI_ERR_STATUS_0;
+ break;
+
+ case MSS_HUB_POISON_RSP_INTMASK:
+ status_reg = MSS_HUB_POISON_RSP_STATUS_0;
+ break;
+
+ case MSS_HUB_RESTRICTED_ACCESS_ERR_INTMASK:
+ status_reg = MSS_HUB_RESTRICTED_ACCESS_ERR_STATUS_0;
+ break;
+
+ case MSS_HUB_RESERVED_PA_ERR_INTMASK:
+ status_reg = MSS_HUB_RESERVED_PA_ERR_STATUS_0;
+ break;
+
+ default:
+ dev_err_ratelimited(mc->dev, "Incorrect HUB interrupt mask\n");
+ return;
+ }
+
+ value = mc_ch_readl(mc, hub, status_reg);
+
+ client_id = value & mc->soc->client_id_mask;
+ for (i = 0; i < mc->soc->num_clients; i++) {
+ if (mc->soc->clients[i].id == client_id) {
+ client = mc->soc->clients[i].name;
+ break;
+ }
+ }
+
+ dev_err_ratelimited(mc->dev, "%s: @%pa: %s status: 0x%x\n",
+ client, &addr, tegra264_hub_error_names[bit] ?: "unknown",
+ value);
+ }
+
+ /* clear interrupts */
+ mc_ch_writel(mc, hub, hub_intstat, MSS_HUB_INTRSTATUS_0);
+}
+
+static irqreturn_t handle_hub_irq(int irq, void *data, int mc_hubc_aperture_number)
+{
+ struct tegra_mc *mc = data;
+ u32 global_intstat;
+ unsigned long hub_interrupt, intstat, hub;
+
+ /* Read MSS_HUB_GLOBAL_INTSTATUS_0 from mc_hubc_aperture_number block */
+ global_intstat = mc_ch_readl(mc, mc_hubc_aperture_number, MSS_HUB_GLOBAL_INTSTATUS_0);
+ if (global_intstat == 0) {
+ dev_warn(mc->dev, "No interrupt in HUB/HUBC\n");
+ return IRQ_NONE;
+ }
+
+ /* Handle interrupt from hubc */
+ if (global_intstat & MSS_HUBC_INTR) {
+ /* Read MSS_HUB_HUBC_INTSTATUS_0 from block mc_hubc_aperture_number */
+ intstat = mc_ch_readl(mc, mc_hubc_aperture_number, MSS_HUB_HUBC_INTSTATUS_0);
+ if (intstat != 0) {
+ dev_err_ratelimited(mc->dev, "Scrubber operation status: 0x%lx\n",
+ intstat);
+ /* Clear hubc interrupt */
+ mc_ch_writel(mc, mc_hubc_aperture_number, intstat,
+ MSS_HUB_HUBC_INTSTATUS_0);
+ }
+ }
+
+ hub_interrupt = (global_intstat & MSS_HUB_GLOBAL_MASK) >> MSS_HUB_GLOBAL_SHIFT;
+ /* Handle interrupt from hub */
+ for_each_set_bit(hub, &hub_interrupt, 32) {
+ /* Read MSS_HUB_INTRSTATUS_0 from block MCi */
+ intstat = mc_ch_readl(mc, hub, MSS_HUB_INTRSTATUS_0);
+ if (intstat != 0)
+ hub_log_fault(mc, hub, intstat);
+ }
+
+ /* Clear global interrupt status register */
+ mc_ch_writel(mc, mc_hubc_aperture_number, global_intstat, MSS_HUB_GLOBAL_INTSTATUS_0);
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t handle_disp_hub_irq(int irq, void *data)
+{
+ return handle_hub_irq(irq, data, mc_hubc_aperture_number[0]);
+}
+
+static irqreturn_t handle_system_hub_irq(int irq, void *data)
+{
+ return handle_hub_irq(irq, data, mc_hubc_aperture_number[1]);
+}
+
+static irqreturn_t handle_vision_hub_irq(int irq, void *data)
+{
+ return handle_hub_irq(irq, data, mc_hubc_aperture_number[2]);
+}
+
+static irqreturn_t handle_uphy_hub_irq(int irq, void *data)
+{
+ return handle_hub_irq(irq, data, mc_hubc_aperture_number[3]);
+}
+
+static irqreturn_t handle_top_hub_irq(int irq, void *data)
+{
+ return handle_hub_irq(irq, data, mc_hubc_aperture_number[4]);
+}
+
+static irqreturn_t handle_generic_irq(struct tegra_mc *mc, unsigned long intstat_reg)
+{
+ u32 intstat, i;
+
+ /* Iterate over all MC blocks to read INTSTATUS */
+ for (i = 0; i < mc->num_channels; i++) {
+ intstat = mc_ch_readl(mc, i, intstat_reg);
+ if (intstat) {
+ dev_err_ratelimited(mc->dev, "channel: %i status: 0x%x\n", i, intstat);
+ /* Clear interrupt */
+ mc_ch_writel(mc, i, intstat, intstat_reg);
+ }
+ }
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t handle_sbs_irq(int irq, void *data)
+{
+ return handle_generic_irq((struct tegra_mc *)data, MSS_SBS_INTSTATUS_0);
+}
+
+static irqreturn_t handle_channel_irq(int irq, void *data)
+{
+ return handle_generic_irq((struct tegra_mc *)data, MC_CH_INTSTATUS_0);
+}
+
+static const irq_handler_t tegra264_mc_irq_handlers[8] = {
+ handle_mcf_irq, handle_disp_hub_irq, handle_vision_hub_irq,
+ handle_system_hub_irq, handle_uphy_hub_irq, handle_top_hub_irq,
+ handle_sbs_irq, handle_channel_irq
+};
+
static const struct tegra_mc_icc_ops tegra264_mc_icc_ops = {
.xlate = tegra_mc_icc_xlate,
.aggregate = tegra264_mc_icc_aggregate,
@@ -290,16 +631,80 @@ static const struct tegra_mc_icc_ops tegra264_mc_icc_ops = {
.set = tegra264_mc_icc_set,
};
+static const struct tegra_mc_regs tegra264_mc_regs = {
+ .cfg_channel_enable = 0x8870,
+ .err_status = 0xbc00,
+ .err_add = 0xbc04,
+ .err_add_hi = 0xbc08,
+ .err_vpr_status = 0xbc20,
+ .err_vpr_add = 0xbc24,
+ .err_sec_status = 0xbc3c,
+ .err_sec_add = 0xbc40,
+ .err_mts_status = 0xbc5c,
+ .err_mts_add = 0xbc60,
+ .err_gen_co_status = 0xbc78,
+ .err_gen_co_add = 0xbc7c,
+ .err_route_status = 0xbc64,
+ .err_route_add = 0xbc68,
+};
+
+static const struct tegra_mc_intmask tegra264_mc_intmasks[] = {
+ {
+ .reg = MCF_INTMASK_0,
+ .mask = MC_INT_DECERR_ROUTE_SANITY_GIC_MSI | MC_INT_DECERR_ROUTE_SANITY |
+ MC_INT_DECERR_GENERALIZED_CARVEOUT | MC_INT_DECERR_MTS |
+ MC_INT_SECERR_SEC | MC_INT_DECERR_VPR | MC_INT_SECURITY_VIOLATION |
+ MC_INT_DECERR_EMEM,
+ },
+ {
+ .reg = MCF_INTPRIORITY_0,
+ .mask = MC_INT_DECERR_ROUTE_SANITY_GIC_MSI | MC_INT_DECERR_ROUTE_SANITY |
+ MC_INT_DECERR_GENERALIZED_CARVEOUT | MC_INT_DECERR_MTS |
+ MC_INT_SECERR_SEC | MC_INT_DECERR_VPR | MC_INT_SECURITY_VIOLATION |
+ MC_INT_DECERR_EMEM,
+ },
+ {
+ .reg = MSS_HUB_INTRMASK_0,
+ .mask = MSS_HUB_COALESCER_ERR_INTMASK | MSS_HUB_SMMU_BYPASS_ALLOW_ERR_INTMASK |
+ MSS_HUB_ILLEGAL_TBUGRP_ID_INTMASK | MSS_HUB_MSI_ERR_INTMASK |
+ MSS_HUB_POISON_RSP_INTMASK | MSS_HUB_RESTRICTED_ACCESS_ERR_INTMASK |
+ MSS_HUB_RESERVED_PA_ERR_INTMASK,
+ },
+ {
+ .reg = MSS_HUB_INTRPRIORITY_0,
+ .mask = MSS_HUB_COALESCER_ERR_INTMASK | MSS_HUB_SMMU_BYPASS_ALLOW_ERR_INTMASK |
+ MSS_HUB_ILLEGAL_TBUGRP_ID_INTMASK | MSS_HUB_MSI_ERR_INTMASK |
+ MSS_HUB_POISON_RSP_INTMASK | MSS_HUB_RESTRICTED_ACCESS_ERR_INTMASK |
+ MSS_HUB_RESERVED_PA_ERR_INTMASK,
+ },
+ {
+ .reg = MSS_HUB_HUBC_INTMASK_0,
+ .mask = MSS_HUB_HUBC_SCRUB_DONE_INTMASK,
+ },
+ {
+ .reg = MSS_HUB_HUBC_INTPRIORITY_0,
+ .mask = MSS_HUB_HUBC_SCRUB_DONE_INTMASK,
+ },
+ {
+ .reg = MSS_SBS_INTMASK_0,
+ .mask = MSS_SBS_FILL_FIFO_ISO_OVERFLOW_INTMASK |
+ MSS_SBS_FILL_FIFO_SISO_OVERFLOW_INTMASK |
+ MSS_SBS_FILL_FIFO_NISO_OVERFLOW_INTMASK,
+ },
+ {
+ .reg = MC_CH_INTMASK_0,
+ .mask = WCAM_ERR_INTMASK,
+ }
+};
+
const struct tegra_mc_soc tegra264_mc_soc = {
.num_clients = ARRAY_SIZE(tegra264_mc_clients),
.clients = tegra264_mc_clients,
.num_address_bits = 40,
.num_channels = 16,
.client_id_mask = 0x1ff,
- .intmask = MC_INT_DECERR_ROUTE_SANITY |
- MC_INT_DECERR_GENERALIZED_CARVEOUT | MC_INT_DECERR_MTS |
- MC_INT_SECERR_SEC | MC_INT_DECERR_VPR |
- MC_INT_SECURITY_VIOLATION | MC_INT_DECERR_EMEM,
+ .intmasks = tegra264_mc_intmasks,
+ .num_intmasks = ARRAY_SIZE(tegra264_mc_intmasks),
.has_addr_hi_reg = true,
.ops = &tegra186_mc_ops,
.icc_ops = &tegra264_mc_icc_ops,
@@ -310,4 +715,9 @@ const struct tegra_mc_soc tegra264_mc_soc = {
* supported.
*/
.num_carveouts = 32,
+ .mc_addr_hi_mask = 0xff,
+ .mc_err_status_type_mask = (0x3 << 28),
+ .regs = &tegra264_mc_regs,
+ .handle_irq = tegra264_mc_irq_handlers,
+ .num_interrupts = ARRAY_SIZE(tegra264_mc_irq_handlers),
};
diff --git a/drivers/memory/tegra/tegra30-emc.c b/drivers/memory/tegra/tegra30-emc.c
index 606106dd2b32..5812c8cd6ce4 100644
--- a/drivers/memory/tegra/tegra30-emc.c
+++ b/drivers/memory/tegra/tegra30-emc.c
@@ -554,14 +554,14 @@ static int emc_prepare_timing_change(struct tegra_emc *emc, unsigned long rate)
emc->emc_cfg = readl_relaxed(emc->regs + EMC_CFG);
emc_dbg = readl_relaxed(emc->regs + EMC_DBG);
- if (emc->dll_on == !!(timing->emc_mode_1 & 0x1))
+ if (emc->dll_on == !(timing->emc_mode_1 & 0x1))
dll_change = DLL_CHANGE_NONE;
- else if (timing->emc_mode_1 & 0x1)
+ else if (!(timing->emc_mode_1 & 0x1))
dll_change = DLL_CHANGE_ON;
else
dll_change = DLL_CHANGE_OFF;
- emc->dll_on = !!(timing->emc_mode_1 & 0x1);
+ emc->dll_on = !(timing->emc_mode_1 & 0x1);
if (timing->data[80] && !readl_relaxed(emc->regs + EMC_ZCAL_INTERVAL))
emc->zcal_long = true;
diff --git a/drivers/memory/tegra/tegra30.c b/drivers/memory/tegra/tegra30.c
index a6bcde4b92c0..8389e3af0121 100644
--- a/drivers/memory/tegra/tegra30.c
+++ b/drivers/memory/tegra/tegra30.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
- * Copyright (C) 2014 NVIDIA CORPORATION. All rights reserved.
+ * Copyright (C) 2014-2026 NVIDIA CORPORATION. All rights reserved.
*/
#include <linux/device.h>
@@ -1384,6 +1384,14 @@ static const struct tegra_mc_icc_ops tegra30_mc_icc_ops = {
.set = tegra30_mc_icc_set,
};
+static const struct tegra_mc_intmask tegra30_mc_intmasks[] = {
+ {
+ .reg = MC_INTMASK,
+ .mask = MC_INT_INVALID_SMMU_PAGE | MC_INT_SECURITY_VIOLATION |
+ MC_INT_DECERR_EMEM,
+ },
+};
+
const struct tegra_mc_soc tegra30_mc_soc = {
.clients = tegra30_mc_clients,
.num_clients = ARRAY_SIZE(tegra30_mc_clients),
@@ -1393,11 +1401,15 @@ const struct tegra_mc_soc tegra30_mc_soc = {
.smmu = &tegra30_smmu_soc,
.emem_regs = tegra30_mc_emem_regs,
.num_emem_regs = ARRAY_SIZE(tegra30_mc_emem_regs),
- .intmask = MC_INT_INVALID_SMMU_PAGE | MC_INT_SECURITY_VIOLATION |
- MC_INT_DECERR_EMEM,
+ .intmasks = tegra30_mc_intmasks,
+ .num_intmasks = ARRAY_SIZE(tegra30_mc_intmasks),
.reset_ops = &tegra_mc_reset_ops_common,
.resets = tegra30_mc_resets,
.num_resets = ARRAY_SIZE(tegra30_mc_resets),
.icc_ops = &tegra30_mc_icc_ops,
.ops = &tegra30_mc_ops,
+ .regs = &tegra20_mc_regs,
+ .handle_irq = tegra30_mc_irq_handlers,
+ .num_interrupts = ARRAY_SIZE(tegra30_mc_irq_handlers),
+ .mc_err_status_type_mask = (0x7 << 28),
};
diff --git a/drivers/mfd/sec-acpm.c b/drivers/mfd/sec-acpm.c
index 537ea65685bf..0e23b9d9f7ee 100644
--- a/drivers/mfd/sec-acpm.c
+++ b/drivers/mfd/sec-acpm.c
@@ -367,7 +367,7 @@ static const struct regmap_config s2mpg11_regmap_config_meter = {
};
struct sec_pmic_acpm_shared_bus_context {
- const struct acpm_handle *acpm;
+ struct acpm_handle *acpm;
unsigned int acpm_chan_id;
u8 speedy_channel;
};
@@ -390,7 +390,7 @@ static int sec_pmic_acpm_bus_write(void *context, const void *data,
size_t count)
{
struct sec_pmic_acpm_bus_context *ctx = context;
- const struct acpm_handle *acpm = ctx->shared->acpm;
+ struct acpm_handle *acpm = ctx->shared->acpm;
const struct acpm_pmic_ops *pmic_ops = &acpm->ops.pmic_ops;
size_t val_count = count - BITS_TO_BYTES(ACPM_ADDR_BITS);
const u8 *d = data;
@@ -410,7 +410,7 @@ static int sec_pmic_acpm_bus_read(void *context, const void *reg_buf, size_t reg
void *val_buf, size_t val_size)
{
struct sec_pmic_acpm_bus_context *ctx = context;
- const struct acpm_handle *acpm = ctx->shared->acpm;
+ struct acpm_handle *acpm = ctx->shared->acpm;
const struct acpm_pmic_ops *pmic_ops = &acpm->ops.pmic_ops;
const u8 *r = reg_buf;
u8 reg;
@@ -429,7 +429,7 @@ static int sec_pmic_acpm_bus_reg_update_bits(void *context, unsigned int reg, un
unsigned int val)
{
struct sec_pmic_acpm_bus_context *ctx = context;
- const struct acpm_handle *acpm = ctx->shared->acpm;
+ struct acpm_handle *acpm = ctx->shared->acpm;
const struct acpm_pmic_ops *pmic_ops = &acpm->ops.pmic_ops;
return pmic_ops->update_reg(acpm, ctx->shared->acpm_chan_id, ctx->type, reg & 0xff,
@@ -480,7 +480,7 @@ static int sec_pmic_acpm_probe(struct platform_device *pdev)
struct regmap *regmap_common, *regmap_pmic, *regmap;
const struct sec_pmic_acpm_platform_data *pdata;
struct sec_pmic_acpm_shared_bus_context *shared_ctx;
- const struct acpm_handle *acpm;
+ struct acpm_handle *acpm;
struct device *dev = &pdev->dev;
int ret, irq;
diff --git a/drivers/pinctrl/stm32/pinctrl-stm32-hdp.c b/drivers/pinctrl/stm32/pinctrl-stm32-hdp.c
index 0b1dff01e04c..cce477e86ef9 100644
--- a/drivers/pinctrl/stm32/pinctrl-stm32-hdp.c
+++ b/drivers/pinctrl/stm32/pinctrl-stm32-hdp.c
@@ -4,6 +4,7 @@
* Author: Clément Le Goffic <clement.legoffic@foss.st.com> for STMicroelectronics.
*/
#include <linux/bits.h>
+#include <linux/bus/stm32_firewall_device.h>
#include <linux/clk.h>
#include <linux/gpio/driver.h>
#include <linux/gpio/generic.h>
@@ -46,9 +47,11 @@ struct stm32_hdp {
void __iomem *base;
struct clk *clk;
struct pinctrl_dev *pctl_dev;
+ struct stm32_firewall *firewall;
struct gpio_generic_chip gpio_chip;
u32 mux_conf;
u32 gposet_conf;
+ int nb_firewall_entries;
const char * const *func_name;
};
@@ -615,6 +618,13 @@ static int stm32_hdp_probe(struct platform_device *pdev)
return -ENOMEM;
hdp->dev = dev;
+ if (IS_ENABLED(CONFIG_STM32_FIREWALL)) {
+ err = stm32_firewall_get_grant_all_access(dev, &hdp->firewall,
+ &hdp->nb_firewall_entries);
+ if (err)
+ return err;
+ }
+
platform_set_drvdata(pdev, hdp);
hdp->base = devm_platform_ioremap_resource(pdev, 0);
@@ -670,8 +680,12 @@ static int stm32_hdp_probe(struct platform_device *pdev)
static void stm32_hdp_remove(struct platform_device *pdev)
{
struct stm32_hdp *hdp = platform_get_drvdata(pdev);
+ int i;
writel_relaxed(HDP_CTRL_DISABLE, hdp->base + HDP_CTRL);
+
+ for (i = 0; i < hdp->nb_firewall_entries; i++)
+ stm32_firewall_release_access(&hdp->firewall[i]);
}
static int stm32_hdp_suspend(struct device *dev)
diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
index 7ce151f6a7e4..2fda1d9622f4 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -257,6 +257,8 @@ config RESET_RZG2L_USBPHY_CTRL
config RESET_RZV2H_USB2PHY
tristate "Renesas RZ/V2H(P) (and similar SoCs) USB2PHY Reset driver"
depends on ARCH_RENESAS || COMPILE_TEST
+ select AUXILIARY_BUS
+ select REGMAP_MMIO
help
Support for USB2PHY Port reset Control found on the RZ/V2H(P) SoC
(and similar SoCs).
@@ -291,6 +293,13 @@ config RESET_SIMPLE
- SiFive FU740 SoCs
- Sophgo SoCs
+config RESET_SKY1
+ bool "Cix Sky1 reset controller"
+ depends on ARCH_CIX || COMPILE_TEST
+ select REGMAP_MMIO
+ help
+ This enables the reset controller for Cix Sky1.
+
config RESET_SOCFPGA
bool "SoCFPGA Reset Driver" if COMPILE_TEST && (!ARM || !ARCH_INTEL_SOCFPGA)
default ARM && ARCH_INTEL_SOCFPGA
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
index fc0cc99f8514..d1b8c66e5086 100644
--- a/drivers/reset/Makefile
+++ b/drivers/reset/Makefile
@@ -38,6 +38,7 @@ obj-$(CONFIG_RESET_RZG2L_USBPHY_CTRL) += reset-rzg2l-usbphy-ctrl.o
obj-$(CONFIG_RESET_RZV2H_USB2PHY) += reset-rzv2h-usb2phy.o
obj-$(CONFIG_RESET_SCMI) += reset-scmi.o
obj-$(CONFIG_RESET_SIMPLE) += reset-simple.o
+obj-$(CONFIG_RESET_SKY1) += reset-sky1.o
obj-$(CONFIG_RESET_SOCFPGA) += reset-socfpga.o
obj-$(CONFIG_RESET_SUNPLUS) += reset-sunplus.o
obj-$(CONFIG_RESET_SUNXI) += reset-sunxi.o
diff --git a/drivers/reset/core.c b/drivers/reset/core.c
index 352c2360603b..38e189d04d09 100644
--- a/drivers/reset/core.c
+++ b/drivers/reset/core.c
@@ -12,6 +12,7 @@
#include <linux/device.h>
#include <linux/err.h>
#include <linux/export.h>
+#include <linux/fwnode.h>
#include <linux/gpio/driver.h>
#include <linux/gpio/machine.h>
#include <linux/gpio/property.h>
@@ -20,9 +21,11 @@
#include <linux/kref.h>
#include <linux/module.h>
#include <linux/of.h>
+#include <linux/property.h>
#include <linux/reset.h>
#include <linux/reset-controller.h>
#include <linux/slab.h>
+#include <linux/srcu.h>
static DEFINE_MUTEX(reset_list_mutex);
static LIST_HEAD(reset_controller_list);
@@ -36,6 +39,7 @@ static DEFINE_IDA(reset_gpio_ida);
* struct reset_control - a reset control
* @rcdev: a pointer to the reset controller device
* this reset control belongs to
+ * @srcu: protects the rcdev pointer from removal during consumer access
* @list: list entry for the rcdev's reset controller list
* @id: ID of the reset controller in the reset
* controller device
@@ -47,9 +51,11 @@ static DEFINE_IDA(reset_gpio_ida);
* @triggered_count: Number of times this reset line has been reset. Currently
* only used for shared resets, which means that the value
* will be either 0 or 1.
+ * @lock: serializes the internals of reset_control_acquire()
*/
struct reset_control {
- struct reset_controller_dev *rcdev;
+ struct reset_controller_dev __rcu *rcdev;
+ struct srcu_struct srcu;
struct list_head list;
unsigned int id;
struct kref refcnt;
@@ -58,6 +64,7 @@ struct reset_control {
bool array;
atomic_t deassert_count;
atomic_t triggered_count;
+ struct mutex lock;
};
/**
@@ -74,14 +81,16 @@ struct reset_control_array {
/**
* struct reset_gpio_lookup - lookup key for ad-hoc created reset-gpio devices
- * @of_args: phandle to the reset controller with all the args like GPIO number
+ * @ref_args: Reference to the reset controller with all the args like GPIO number
* @swnode: Software node containing the reference to the GPIO provider
* @list: list entry for the reset_gpio_lookup_list
+ * @adev: Auxiliary device representing the reset controller
*/
struct reset_gpio_lookup {
- struct of_phandle_args of_args;
+ struct fwnode_reference_args ref_args;
struct fwnode_handle *swnode;
struct list_head list;
+ struct auxiliary_device adev;
};
static const char *rcdev_name(struct reset_controller_dev *rcdev)
@@ -89,27 +98,24 @@ static const char *rcdev_name(struct reset_controller_dev *rcdev)
if (rcdev->dev)
return dev_name(rcdev->dev);
- if (rcdev->of_node)
- return rcdev->of_node->full_name;
-
- if (rcdev->of_args)
- return rcdev->of_args->np->full_name;
+ if (rcdev->fwnode)
+ return fwnode_get_name(rcdev->fwnode);
return NULL;
}
/**
- * of_reset_simple_xlate - translate reset_spec to the reset line number
+ * fwnode_reset_simple_xlate - translate reset_spec to the reset line number
* @rcdev: a pointer to the reset controller device
- * @reset_spec: reset line specifier as found in the device tree
+ * @reset_spec: reset line specifier as found in firmware
*
- * This static translation function is used by default if of_xlate in
- * :c:type:`reset_controller_dev` is not set. It is useful for all reset
- * controllers with 1:1 mapping, where reset lines can be indexed by number
- * without gaps.
+ * This static translation function is used by default if neither fwnode_xlate
+ * not of_xlate in :c:type:`reset_controller_dev` is not set. It is useful for
+ * all reset controllers with 1:1 mapping, where reset lines can be indexed by
+ * number without gaps.
*/
-static int of_reset_simple_xlate(struct reset_controller_dev *rcdev,
- const struct of_phandle_args *reset_spec)
+static int fwnode_reset_simple_xlate(struct reset_controller_dev *rcdev,
+ const struct fwnode_reference_args *reset_spec)
{
if (reset_spec->args[0] >= rcdev->nr_resets)
return -EINVAL;
@@ -123,33 +129,71 @@ static int of_reset_simple_xlate(struct reset_controller_dev *rcdev,
*/
int reset_controller_register(struct reset_controller_dev *rcdev)
{
- if (rcdev->of_node && rcdev->of_args)
+ if ((rcdev->of_node && rcdev->fwnode) || (rcdev->of_xlate && rcdev->fwnode_xlate))
return -EINVAL;
- if (!rcdev->of_xlate) {
- rcdev->of_reset_n_cells = 1;
- rcdev->of_xlate = of_reset_simple_xlate;
+ if (rcdev->of_node && !rcdev->fwnode)
+ rcdev->fwnode = of_fwnode_handle(rcdev->of_node);
+
+ if (!rcdev->fwnode) {
+ rcdev->fwnode = dev_fwnode(rcdev->dev);
+ if (!rcdev->fwnode)
+ return -EINVAL;
+ }
+
+ if (rcdev->of_xlate)
+ rcdev->fwnode_reset_n_cells = rcdev->of_reset_n_cells;
+
+ if (!rcdev->fwnode_xlate && !rcdev->of_xlate) {
+ rcdev->fwnode_xlate = fwnode_reset_simple_xlate;
+ rcdev->fwnode_reset_n_cells = 1;
}
INIT_LIST_HEAD(&rcdev->reset_control_head);
+ mutex_init(&rcdev->lock);
+
+ guard(mutex)(&reset_list_mutex);
- mutex_lock(&reset_list_mutex);
list_add(&rcdev->list, &reset_controller_list);
- mutex_unlock(&reset_list_mutex);
return 0;
}
EXPORT_SYMBOL_GPL(reset_controller_register);
+static void reset_controller_remove(struct reset_controller_dev *rcdev,
+ struct reset_control *rstc)
+{
+ lockdep_assert_held(&rcdev->lock);
+
+ list_del(&rstc->list);
+ module_put(rcdev->owner);
+ put_device(rcdev->dev);
+}
+
/**
* reset_controller_unregister - unregister a reset controller device
* @rcdev: a pointer to the reset controller device
*/
void reset_controller_unregister(struct reset_controller_dev *rcdev)
{
- mutex_lock(&reset_list_mutex);
- list_del(&rcdev->list);
- mutex_unlock(&reset_list_mutex);
+ struct reset_control *rstc, *pos;
+
+ scoped_guard(mutex, &reset_list_mutex)
+ list_del(&rcdev->list);
+
+ scoped_guard(mutex, &rcdev->lock) {
+ /*
+ * Numb but don't free the remaining reset control handles that are
+ * still held by consumers.
+ */
+ list_for_each_entry_safe(rstc, pos, &rcdev->reset_control_head, list) {
+ rcu_assign_pointer(rstc->rcdev, NULL);
+ synchronize_srcu(&rstc->srcu);
+ reset_controller_remove(rcdev, rstc);
+ }
+ }
+
+ mutex_destroy(&rcdev->lock);
}
EXPORT_SYMBOL_GPL(reset_controller_unregister);
@@ -326,6 +370,7 @@ static inline bool reset_control_is_array(struct reset_control *rstc)
*/
int reset_control_reset(struct reset_control *rstc)
{
+ struct reset_controller_dev *rcdev;
int ret;
if (!rstc)
@@ -337,7 +382,13 @@ int reset_control_reset(struct reset_control *rstc)
if (reset_control_is_array(rstc))
return reset_control_array_reset(rstc_to_array(rstc));
- if (!rstc->rcdev->ops->reset)
+ guard(srcu)(&rstc->srcu);
+
+ rcdev = srcu_dereference(rstc->rcdev, &rstc->srcu);
+ if (!rcdev)
+ return -ENODEV;
+
+ if (!rcdev->ops->reset)
return -ENOTSUPP;
if (rstc->shared) {
@@ -351,7 +402,7 @@ int reset_control_reset(struct reset_control *rstc)
return -EPERM;
}
- ret = rstc->rcdev->ops->reset(rstc->rcdev, rstc->id);
+ ret = rcdev->ops->reset(rcdev, rstc->id);
if (rstc->shared && ret)
atomic_dec(&rstc->triggered_count);
@@ -384,7 +435,7 @@ int reset_control_bulk_reset(int num_rstcs,
EXPORT_SYMBOL_GPL(reset_control_bulk_reset);
/**
- * reset_control_rearm - allow shared reset line to be re-triggered"
+ * reset_control_rearm - allow shared reset line to be re-triggered
* @rstc: reset controller
*
* On a shared reset line the actual reset pulse is only triggered once for the
@@ -441,6 +492,8 @@ EXPORT_SYMBOL_GPL(reset_control_rearm);
*/
int reset_control_assert(struct reset_control *rstc)
{
+ struct reset_controller_dev *rcdev;
+
if (!rstc)
return 0;
@@ -450,6 +503,12 @@ int reset_control_assert(struct reset_control *rstc)
if (reset_control_is_array(rstc))
return reset_control_array_assert(rstc_to_array(rstc));
+ guard(srcu)(&rstc->srcu);
+
+ rcdev = srcu_dereference(rstc->rcdev, &rstc->srcu);
+ if (!rcdev)
+ return -ENODEV;
+
if (rstc->shared) {
if (WARN_ON(atomic_read(&rstc->triggered_count) != 0))
return -EINVAL;
@@ -464,7 +523,7 @@ int reset_control_assert(struct reset_control *rstc)
* Shared reset controls allow the reset line to be in any state
* after this call, so doing nothing is a valid option.
*/
- if (!rstc->rcdev->ops->assert)
+ if (!rcdev->ops->assert)
return 0;
} else {
/*
@@ -472,17 +531,17 @@ int reset_control_assert(struct reset_control *rstc)
* is no way to guarantee that the reset line is asserted after
* this call.
*/
- if (!rstc->rcdev->ops->assert)
+ if (!rcdev->ops->assert)
return -ENOTSUPP;
if (!rstc->acquired) {
WARN(1, "reset %s (ID: %u) is not acquired\n",
- rcdev_name(rstc->rcdev), rstc->id);
+ rcdev_name(rcdev), rstc->id);
return -EPERM;
}
}
- return rstc->rcdev->ops->assert(rstc->rcdev, rstc->id);
+ return rcdev->ops->assert(rcdev, rstc->id);
}
EXPORT_SYMBOL_GPL(reset_control_assert);
@@ -529,6 +588,8 @@ EXPORT_SYMBOL_GPL(reset_control_bulk_assert);
*/
int reset_control_deassert(struct reset_control *rstc)
{
+ struct reset_controller_dev *rcdev;
+
if (!rstc)
return 0;
@@ -538,6 +599,12 @@ int reset_control_deassert(struct reset_control *rstc)
if (reset_control_is_array(rstc))
return reset_control_array_deassert(rstc_to_array(rstc));
+ guard(srcu)(&rstc->srcu);
+
+ rcdev = srcu_dereference(rstc->rcdev, &rstc->srcu);
+ if (!rcdev)
+ return -ENODEV;
+
if (rstc->shared) {
if (WARN_ON(atomic_read(&rstc->triggered_count) != 0))
return -EINVAL;
@@ -547,7 +614,7 @@ int reset_control_deassert(struct reset_control *rstc)
} else {
if (!rstc->acquired) {
WARN(1, "reset %s (ID: %u) is not acquired\n",
- rcdev_name(rstc->rcdev), rstc->id);
+ rcdev_name(rcdev), rstc->id);
return -EPERM;
}
}
@@ -559,10 +626,10 @@ int reset_control_deassert(struct reset_control *rstc)
* case, the reset controller driver should implement .deassert() and
* return -ENOTSUPP.
*/
- if (!rstc->rcdev->ops->deassert)
+ if (!rcdev->ops->deassert)
return 0;
- return rstc->rcdev->ops->deassert(rstc->rcdev, rstc->id);
+ return rcdev->ops->deassert(rcdev, rstc->id);
}
EXPORT_SYMBOL_GPL(reset_control_deassert);
@@ -604,14 +671,22 @@ EXPORT_SYMBOL_GPL(reset_control_bulk_deassert);
*/
int reset_control_status(struct reset_control *rstc)
{
+ struct reset_controller_dev *rcdev;
+
if (!rstc)
return 0;
if (WARN_ON(IS_ERR(rstc)) || reset_control_is_array(rstc))
return -EINVAL;
- if (rstc->rcdev->ops->status)
- return rstc->rcdev->ops->status(rstc->rcdev, rstc->id);
+ guard(srcu)(&rstc->srcu);
+
+ rcdev = srcu_dereference(rstc->rcdev, &rstc->srcu);
+ if (!rcdev)
+ return -ENODEV;
+
+ if (rcdev->ops->status)
+ return rcdev->ops->status(rcdev, rstc->id);
return -ENOTSUPP;
}
@@ -639,6 +714,7 @@ EXPORT_SYMBOL_GPL(reset_control_status);
*/
int reset_control_acquire(struct reset_control *rstc)
{
+ struct reset_controller_dev *rcdev;
struct reset_control *rc;
if (!rstc)
@@ -650,25 +726,28 @@ int reset_control_acquire(struct reset_control *rstc)
if (reset_control_is_array(rstc))
return reset_control_array_acquire(rstc_to_array(rstc));
- mutex_lock(&reset_list_mutex);
+ guard(mutex)(&rstc->lock);
- if (rstc->acquired) {
- mutex_unlock(&reset_list_mutex);
+ if (rstc->acquired)
return 0;
- }
- list_for_each_entry(rc, &rstc->rcdev->reset_control_head, list) {
- if (rstc != rc && rstc->id == rc->id) {
- if (rc->acquired) {
- mutex_unlock(&reset_list_mutex);
- return -EBUSY;
+ guard(srcu)(&rstc->srcu);
+
+ rcdev = srcu_dereference(rstc->rcdev, &rstc->srcu);
+ if (!rcdev)
+ return -ENODEV;
+
+ scoped_guard(mutex, &rcdev->lock) {
+ list_for_each_entry(rc, &rcdev->reset_control_head, list) {
+ if (rstc != rc && rstc->id == rc->id) {
+ if (rc->acquired)
+ return -EBUSY;
}
}
}
rstc->acquired = true;
- mutex_unlock(&reset_list_mutex);
return 0;
}
EXPORT_SYMBOL_GPL(reset_control_acquire);
@@ -752,8 +831,9 @@ __reset_control_get_internal(struct reset_controller_dev *rcdev,
bool shared = flags & RESET_CONTROL_FLAGS_BIT_SHARED;
bool acquired = flags & RESET_CONTROL_FLAGS_BIT_ACQUIRED;
struct reset_control *rstc;
+ int ret;
- lockdep_assert_held(&reset_list_mutex);
+ lockdep_assert_held(&rcdev->lock);
/* Expect callers to filter out OPTIONAL and DEASSERTED bits */
if (WARN_ON(flags & ~(RESET_CONTROL_FLAGS_BIT_SHARED |
@@ -782,15 +862,23 @@ __reset_control_get_internal(struct reset_controller_dev *rcdev,
if (!rstc)
return ERR_PTR(-ENOMEM);
+ ret = init_srcu_struct(&rstc->srcu);
+ if (ret) {
+ kfree(rstc);
+ return ERR_PTR(ret);
+ }
+
if (!try_module_get(rcdev->owner)) {
+ cleanup_srcu_struct(&rstc->srcu);
kfree(rstc);
return ERR_PTR(-ENODEV);
}
- rstc->rcdev = rcdev;
+ rcu_assign_pointer(rstc->rcdev, rcdev);
list_add(&rstc->list, &rcdev->reset_control_head);
rstc->id = index;
kref_init(&rstc->refcnt);
+ mutex_init(&rstc->lock);
rstc->acquired = acquired;
rstc->shared = shared;
get_device(rcdev->dev);
@@ -802,76 +890,133 @@ static void __reset_control_release(struct kref *kref)
{
struct reset_control *rstc = container_of(kref, struct reset_control,
refcnt);
+ struct reset_controller_dev *rcdev;
- lockdep_assert_held(&reset_list_mutex);
+ lockdep_assert_held(&rstc->srcu);
- module_put(rstc->rcdev->owner);
+ rcdev = rcu_replace_pointer(rstc->rcdev, NULL, true);
+ if (rcdev) {
+ lockdep_assert_held(&rcdev->lock);
+ reset_controller_remove(rcdev, rstc);
+ }
- list_del(&rstc->list);
- put_device(rstc->rcdev->dev);
- kfree(rstc);
+ mutex_destroy(&rstc->lock);
}
-static void __reset_control_put_internal(struct reset_control *rstc)
+static void reset_control_put_internal(struct reset_control *rstc)
{
- lockdep_assert_held(&reset_list_mutex);
+ struct reset_controller_dev *rcdev;
+ int ret = 0;
if (IS_ERR_OR_NULL(rstc))
return;
- kref_put(&rstc->refcnt, __reset_control_release);
+ scoped_guard(srcu, &rstc->srcu) {
+ rcdev = srcu_dereference(rstc->rcdev, &rstc->srcu);
+ if (!rcdev)
+ /* Already released. */
+ return;
+
+ guard(mutex)(&rcdev->lock);
+ ret = kref_put(&rstc->refcnt, __reset_control_release);
+ }
+
+ if (ret) {
+ synchronize_srcu(&rstc->srcu);
+ cleanup_srcu_struct(&rstc->srcu);
+ kfree(rstc);
+ }
}
static void reset_gpio_aux_device_release(struct device *dev)
{
- struct auxiliary_device *adev = to_auxiliary_dev(dev);
-
- kfree(adev);
+ WARN(1, "reset-gpio device %s should never have been removed", dev_name(dev));
}
-static int reset_add_gpio_aux_device(struct device *parent,
- struct fwnode_handle *swnode,
- int id, void *pdata)
+static int reset_create_gpio_aux_device(struct reset_gpio_lookup *rgpio_dev,
+ struct device *parent)
{
- struct auxiliary_device *adev;
- int ret;
+ struct auxiliary_device *adev = &rgpio_dev->adev;
+ int ret, id;
- adev = kzalloc_obj(*adev);
- if (!adev)
+ id = ida_alloc(&reset_gpio_ida, GFP_KERNEL);
+ if (id < 0)
return -ENOMEM;
adev->id = id;
adev->name = "gpio";
adev->dev.parent = parent;
- adev->dev.platform_data = pdata;
+ adev->dev.platform_data = &rgpio_dev->ref_args;
adev->dev.release = reset_gpio_aux_device_release;
- device_set_node(&adev->dev, swnode);
+ device_set_node(&adev->dev, rgpio_dev->swnode);
ret = auxiliary_device_init(adev);
if (ret) {
- kfree(adev);
+ ida_free(&reset_gpio_ida, id);
return ret;
}
ret = __auxiliary_device_add(adev, "reset");
if (ret) {
auxiliary_device_uninit(adev);
+ ida_free(&reset_gpio_ida, id);
return ret;
}
- return ret;
+ return 0;
+}
+
+static void reset_gpio_add_devlink(struct fwnode_handle *fwnode,
+ struct reset_gpio_lookup *rgpio_dev)
+{
+ struct device *consumer;
+
+ /*
+ * We must use get_dev_from_fwnode() and not ref_find_device_by_node()
+ * because the latter only considers the platform bus while we want to
+ * get consumers of any kind that can be associated with firmware
+ * nodes: auxiliary, soundwire, etc.
+ */
+ consumer = get_dev_from_fwnode(fwnode);
+ if (consumer) {
+ if (!device_link_add(consumer, &rgpio_dev->adev.dev,
+ DL_FLAG_AUTOREMOVE_CONSUMER))
+ pr_warn("Failed to create a device link between reset-gpio and its consumer");
+
+ put_device(consumer);
+ }
+ /*
+ * else { }
+ *
+ * TODO: If ever there's a case where we need to support shared
+ * reset-gpios retrieved from a device node for which there's no
+ * device present yet, this is where we'd set up a notifier waiting
+ * for the device to appear in the system. This would be a lot of code
+ * that would go unused for now so let's cross that bridge when and if
+ * we get there.
+ */
+}
+
+/* TODO: move it out into drivers/base/ */
+static bool fwnode_reference_args_equal(const struct fwnode_reference_args *left,
+ const struct fwnode_reference_args *right)
+{
+ return left->fwnode == right->fwnode && left->nargs == right->nargs &&
+ !memcmp(left->args, right->args, sizeof(left->args[0]) * left->nargs);
}
/*
- * @args: phandle to the GPIO provider with all the args like GPIO number
+ * @np: OF-node associated with the consumer
+ * @args: Reference to the GPIO provider with all the args like GPIO number
*/
-static int __reset_add_reset_gpio_device(const struct of_phandle_args *args)
+static int __reset_add_reset_gpio_device(struct fwnode_handle *fwnode,
+ const struct fwnode_reference_args *args)
{
struct property_entry properties[3] = { };
- unsigned int offset, of_flags, lflags;
+ unsigned int offset, flags, lflags;
struct reset_gpio_lookup *rgpio_dev;
struct device *parent;
- int id, ret, prop = 0;
+ int ret, prop = 0;
/*
* Currently only #gpio-cells=2 is supported with the meaning of:
@@ -879,7 +1024,7 @@ static int __reset_add_reset_gpio_device(const struct of_phandle_args *args)
* args[1]: GPIO flags
* TODO: Handle other cases.
*/
- if (args->args_count != 2)
+ if (args->nargs != 2)
return -ENOENT;
/*
@@ -890,7 +1035,7 @@ static int __reset_add_reset_gpio_device(const struct of_phandle_args *args)
lockdep_assert_not_held(&reset_list_mutex);
offset = args->args[0];
- of_flags = args->args[1];
+ flags = args->args[1];
/*
* Later we map GPIO flags between OF and Linux, however not all
@@ -900,90 +1045,89 @@ static int __reset_add_reset_gpio_device(const struct of_phandle_args *args)
* FIXME: Find a better way of translating OF flags to GPIO lookup
* flags.
*/
- if (of_flags > GPIO_ACTIVE_LOW) {
+ if (flags > GPIO_ACTIVE_LOW) {
pr_err("reset-gpio code does not support GPIO flags %u for GPIO %u\n",
- of_flags, offset);
+ flags, offset);
return -EINVAL;
}
struct gpio_device *gdev __free(gpio_device_put) =
- gpio_device_find_by_fwnode(of_fwnode_handle(args->np));
+ gpio_device_find_by_fwnode(args->fwnode);
if (!gdev)
return -EPROBE_DEFER;
guard(mutex)(&reset_gpio_lookup_mutex);
list_for_each_entry(rgpio_dev, &reset_gpio_lookup_list, list) {
- if (args->np == rgpio_dev->of_args.np) {
- if (of_phandle_args_equal(args, &rgpio_dev->of_args))
- return 0; /* Already on the list, done */
+ if (fwnode_reference_args_equal(args, &rgpio_dev->ref_args)) {
+ /*
+ * Already on the list, create the device link
+ * and stop here.
+ */
+ reset_gpio_add_devlink(fwnode, rgpio_dev);
+ return 0;
}
}
- lflags = GPIO_PERSISTENT | (of_flags & GPIO_ACTIVE_LOW);
+ lflags = GPIO_PERSISTENT | (flags & GPIO_ACTIVE_LOW);
parent = gpio_device_to_device(gdev);
properties[prop++] = PROPERTY_ENTRY_STRING("compatible", "reset-gpio");
properties[prop++] = PROPERTY_ENTRY_GPIO("reset-gpios", parent->fwnode, offset, lflags);
- id = ida_alloc(&reset_gpio_ida, GFP_KERNEL);
- if (id < 0)
- return id;
-
/* Not freed on success, because it is persisent subsystem data. */
rgpio_dev = kzalloc_obj(*rgpio_dev);
- if (!rgpio_dev) {
- ret = -ENOMEM;
- goto err_ida_free;
- }
+ if (!rgpio_dev)
+ return -ENOMEM;
- rgpio_dev->of_args = *args;
+ rgpio_dev->ref_args = *args;
/*
- * We keep the device_node reference, but of_args.np is put at the end
- * of __of_reset_control_get(), so get it one more time.
+ * We keep the fwnode_handle reference, but ref_args.fwnode is put at
+ * the end of __fwnode_reset_control_get(), so get it one more time.
* Hold reference as long as rgpio_dev memory is valid.
*/
- of_node_get(rgpio_dev->of_args.np);
+ fwnode_handle_get(rgpio_dev->ref_args.fwnode);
rgpio_dev->swnode = fwnode_create_software_node(properties, NULL);
if (IS_ERR(rgpio_dev->swnode)) {
ret = PTR_ERR(rgpio_dev->swnode);
- goto err_put_of_node;
+ goto err_put_fwnode;
}
- ret = reset_add_gpio_aux_device(parent, rgpio_dev->swnode, id,
- &rgpio_dev->of_args);
+ ret = reset_create_gpio_aux_device(rgpio_dev, parent);
if (ret)
goto err_del_swnode;
+ reset_gpio_add_devlink(fwnode, rgpio_dev);
list_add(&rgpio_dev->list, &reset_gpio_lookup_list);
return 0;
err_del_swnode:
fwnode_remove_software_node(rgpio_dev->swnode);
-err_put_of_node:
- of_node_put(rgpio_dev->of_args.np);
+err_put_fwnode:
+ fwnode_handle_put(rgpio_dev->ref_args.fwnode);
kfree(rgpio_dev);
-err_ida_free:
- ida_free(&reset_gpio_ida, id);
return ret;
}
-static struct reset_controller_dev *__reset_find_rcdev(const struct of_phandle_args *args,
- bool gpio_fallback)
+static struct reset_controller_dev *
+__reset_find_rcdev(const struct fwnode_reference_args *args, bool gpio_fallback)
{
+ struct fwnode_reference_args *rc_args;
struct reset_controller_dev *rcdev;
lockdep_assert_held(&reset_list_mutex);
list_for_each_entry(rcdev, &reset_controller_list, list) {
- if (gpio_fallback) {
- if (rcdev->of_args && of_phandle_args_equal(args,
- rcdev->of_args))
+ if (gpio_fallback && rcdev->dev &&
+ device_is_compatible(rcdev->dev, "reset-gpio")) {
+ rc_args = dev_get_platdata(rcdev->dev);
+
+ if (fwnode_reference_args_equal(args, rc_args))
return rcdev;
} else {
- if (args->np == rcdev->of_node)
+ if (args->fwnode == rcdev->fwnode)
return rcdev;
}
}
@@ -992,31 +1136,31 @@ static struct reset_controller_dev *__reset_find_rcdev(const struct of_phandle_a
}
struct reset_control *
-__of_reset_control_get(struct device_node *node, const char *id, int index,
- enum reset_control_flags flags)
+__fwnode_reset_control_get(struct fwnode_handle *fwnode, const char *id, int index,
+ enum reset_control_flags flags)
{
bool optional = flags & RESET_CONTROL_FLAGS_BIT_OPTIONAL;
bool gpio_fallback = false;
- struct reset_control *rstc;
+ struct reset_control *rstc = ERR_PTR(-EINVAL);
struct reset_controller_dev *rcdev;
- struct of_phandle_args args;
- int rstc_id;
+ struct fwnode_reference_args args;
+ struct of_phandle_args of_args;
+ int rstc_id = -EINVAL;
int ret;
- if (!node)
+ if (!fwnode)
return ERR_PTR(-EINVAL);
if (id) {
- index = of_property_match_string(node,
- "reset-names", id);
+ index = fwnode_property_match_string(fwnode, "reset-names", id);
if (index == -EILSEQ)
return ERR_PTR(index);
if (index < 0)
return optional ? NULL : ERR_PTR(-ENOENT);
}
- ret = of_parse_phandle_with_args(node, "resets", "#reset-cells",
- index, &args);
+ ret = fwnode_property_get_reference_args(fwnode, "resets", "#reset-cells",
+ 0, index, &args);
if (ret == -EINVAL)
return ERR_PTR(ret);
if (ret) {
@@ -1027,51 +1171,65 @@ __of_reset_control_get(struct device_node *node, const char *id, int index,
* There can be only one reset-gpio for regular devices, so
* don't bother with the "reset-gpios" phandle index.
*/
- ret = of_parse_phandle_with_args(node, "reset-gpios", "#gpio-cells",
- 0, &args);
+ ret = fwnode_property_get_reference_args(fwnode, "reset-gpios",
+ "#gpio-cells", 0, 0, &args);
if (ret)
return optional ? NULL : ERR_PTR(ret);
gpio_fallback = true;
- ret = __reset_add_reset_gpio_device(&args);
+ ret = __reset_add_reset_gpio_device(fwnode, &args);
if (ret) {
- rstc = ERR_PTR(ret);
- goto out_put;
+ fwnode_handle_put(args.fwnode);
+ return ERR_PTR(ret);
}
}
- mutex_lock(&reset_list_mutex);
+ guard(mutex)(&reset_list_mutex);
+
rcdev = __reset_find_rcdev(&args, gpio_fallback);
if (!rcdev) {
rstc = ERR_PTR(-EPROBE_DEFER);
- goto out_unlock;
+ goto out_put;
}
- if (WARN_ON(args.args_count != rcdev->of_reset_n_cells)) {
+ if (WARN_ON(args.nargs != rcdev->fwnode_reset_n_cells)) {
rstc = ERR_PTR(-EINVAL);
- goto out_unlock;
+ goto out_put;
}
- rstc_id = rcdev->of_xlate(rcdev, &args);
+ if (rcdev->of_xlate && is_of_node(fwnode)) {
+ ret = of_parse_phandle_with_args(to_of_node(fwnode),
+ gpio_fallback ? "reset-gpios" : "resets",
+ gpio_fallback ? "#gpio-cells" : "#reset-cells",
+ gpio_fallback ? 0 : index,
+ &of_args);
+ if (ret) {
+ rstc = ERR_PTR(ret);
+ goto out_put;
+ }
+
+ rstc_id = rcdev->of_xlate(rcdev, &of_args);
+ of_node_put(of_args.np);
+ } else if (rcdev->fwnode_xlate) {
+ rstc_id = rcdev->fwnode_xlate(rcdev, &args);
+ }
if (rstc_id < 0) {
rstc = ERR_PTR(rstc_id);
- goto out_unlock;
+ goto out_put;
}
flags &= ~RESET_CONTROL_FLAGS_BIT_OPTIONAL;
- /* reset_list_mutex also protects the rcdev's reset_control list */
- rstc = __reset_control_get_internal(rcdev, rstc_id, flags);
+ scoped_guard(mutex, &rcdev->lock)
+ rstc = __reset_control_get_internal(rcdev, rstc_id, flags);
-out_unlock:
- mutex_unlock(&reset_list_mutex);
out_put:
- of_node_put(args.np);
+ fwnode_handle_put(args.fwnode);
return rstc;
}
-EXPORT_SYMBOL_GPL(__of_reset_control_get);
+EXPORT_SYMBOL_GPL(__fwnode_reset_control_get);
struct reset_control *__reset_control_get(struct device *dev, const char *id,
int index, enum reset_control_flags flags)
@@ -1079,12 +1237,13 @@ struct reset_control *__reset_control_get(struct device *dev, const char *id,
bool shared = flags & RESET_CONTROL_FLAGS_BIT_SHARED;
bool acquired = flags & RESET_CONTROL_FLAGS_BIT_ACQUIRED;
bool optional = flags & RESET_CONTROL_FLAGS_BIT_OPTIONAL;
+ struct fwnode_handle *fwnode = dev_fwnode(dev);
if (WARN_ON(shared && acquired))
return ERR_PTR(-EINVAL);
- if (dev->of_node)
- return __of_reset_control_get(dev->of_node, id, index, flags);
+ if (fwnode)
+ return __fwnode_reset_control_get(fwnode, id, index, flags);
return optional ? NULL : ERR_PTR(-ENOENT);
}
@@ -1107,10 +1266,9 @@ int __reset_control_bulk_get(struct device *dev, int num_rstcs,
return 0;
err:
- mutex_lock(&reset_list_mutex);
while (i--)
- __reset_control_put_internal(rstcs[i].rstc);
- mutex_unlock(&reset_list_mutex);
+ reset_control_put_internal(rstcs[i].rstc);
+
return ret;
}
EXPORT_SYMBOL_GPL(__reset_control_bulk_get);
@@ -1119,10 +1277,8 @@ static void reset_control_array_put(struct reset_control_array *resets)
{
int i;
- mutex_lock(&reset_list_mutex);
for (i = 0; i < resets->num_rstcs; i++)
- __reset_control_put_internal(resets->rstc[i]);
- mutex_unlock(&reset_list_mutex);
+ reset_control_put_internal(resets->rstc[i]);
kfree(resets);
}
@@ -1140,9 +1296,7 @@ void reset_control_put(struct reset_control *rstc)
return;
}
- mutex_lock(&reset_list_mutex);
- __reset_control_put_internal(rstc);
- mutex_unlock(&reset_list_mutex);
+ reset_control_put_internal(rstc);
}
EXPORT_SYMBOL_GPL(reset_control_put);
@@ -1153,10 +1307,8 @@ EXPORT_SYMBOL_GPL(reset_control_put);
*/
void reset_control_bulk_put(int num_rstcs, struct reset_control_bulk_data *rstcs)
{
- mutex_lock(&reset_list_mutex);
while (num_rstcs--)
- __reset_control_put_internal(rstcs[num_rstcs].rstc);
- mutex_unlock(&reset_list_mutex);
+ reset_control_put_internal(rstcs[num_rstcs].rstc);
}
EXPORT_SYMBOL_GPL(reset_control_bulk_put);
@@ -1317,21 +1469,35 @@ EXPORT_SYMBOL_GPL(__device_reset);
*/
/**
- * of_reset_control_get_count - Count number of resets available with a device
+ * fwnode_reset_control_get_count - Count number of resets available with a device
*
- * @node: device node that contains 'resets'.
+ * @fwnode: firmware node that contains 'resets'.
*
* Returns positive reset count on success, or error number on failure and
* on count being zero.
*/
-static int of_reset_control_get_count(struct device_node *node)
+static int fwnode_reset_control_get_count(struct fwnode_handle *fwnode)
{
- int count;
+ struct fwnode_reference_args args;
+ int count = 0, ret;
- if (!node)
+ if (!fwnode)
return -EINVAL;
- count = of_count_phandle_with_args(node, "resets", "#reset-cells");
+ for (;;) {
+ ret = fwnode_property_get_reference_args(fwnode, "resets", "#reset-cells",
+ 0, count, &args);
+ if (ret) {
+ if (ret == -ENOENT)
+ break;
+
+ return ret;
+ }
+
+ fwnode_handle_put(args.fwnode);
+ count++;
+ }
+
if (count == 0)
count = -ENOENT;
@@ -1339,23 +1505,24 @@ static int of_reset_control_get_count(struct device_node *node)
}
/**
- * of_reset_control_array_get - Get a list of reset controls using
- * device node.
+ * fwnode_reset_control_array_get - Get a list of reset controls using
+ * a firmware node.
*
- * @np: device node for the device that requests the reset controls array
+ * @fwnode: firmware node for the device that requests the reset controls array
* @flags: whether reset controls are shared, optional, acquired
*
* Returns pointer to allocated reset_control on success or error on failure
*/
struct reset_control *
-of_reset_control_array_get(struct device_node *np, enum reset_control_flags flags)
+fwnode_reset_control_array_get(struct fwnode_handle *fwnode,
+ enum reset_control_flags flags)
{
bool optional = flags & RESET_CONTROL_FLAGS_BIT_OPTIONAL;
struct reset_control_array *resets;
struct reset_control *rstc;
int num, i;
- num = of_reset_control_get_count(np);
+ num = fwnode_reset_control_get_count(fwnode);
if (num < 0)
return optional ? NULL : ERR_PTR(num);
@@ -1365,7 +1532,7 @@ of_reset_control_array_get(struct device_node *np, enum reset_control_flags flag
resets->num_rstcs = num;
for (i = 0; i < num; i++) {
- rstc = __of_reset_control_get(np, NULL, i, flags);
+ rstc = __fwnode_reset_control_get(fwnode, NULL, i, flags);
if (IS_ERR(rstc))
goto err_rst;
resets->rstc[i] = rstc;
@@ -1375,16 +1542,14 @@ of_reset_control_array_get(struct device_node *np, enum reset_control_flags flag
return &resets->base;
err_rst:
- mutex_lock(&reset_list_mutex);
while (--i >= 0)
- __reset_control_put_internal(resets->rstc[i]);
- mutex_unlock(&reset_list_mutex);
+ reset_control_put_internal(resets->rstc[i]);
kfree(resets);
return rstc;
}
-EXPORT_SYMBOL_GPL(of_reset_control_array_get);
+EXPORT_SYMBOL_GPL(fwnode_reset_control_array_get);
/**
* devm_reset_control_array_get - Resource managed reset control array get
@@ -1408,7 +1573,7 @@ devm_reset_control_array_get(struct device *dev, enum reset_control_flags flags)
if (!ptr)
return ERR_PTR(-ENOMEM);
- rstc = of_reset_control_array_get(dev->of_node, flags);
+ rstc = fwnode_reset_control_array_get(dev_fwnode(dev), flags);
if (IS_ERR_OR_NULL(rstc)) {
devres_free(ptr);
return rstc;
@@ -1431,8 +1596,10 @@ EXPORT_SYMBOL_GPL(devm_reset_control_array_get);
*/
int reset_control_get_count(struct device *dev)
{
- if (dev->of_node)
- return of_reset_control_get_count(dev->of_node);
+ struct fwnode_handle *fwnode = dev_fwnode(dev);
+
+ if (fwnode)
+ return fwnode_reset_control_get_count(fwnode);
return -ENOENT;
}
diff --git a/drivers/reset/reset-ath79.c b/drivers/reset/reset-ath79.c
index b5d620132052..4c4e69eb32bb 100644
--- a/drivers/reset/reset-ath79.c
+++ b/drivers/reset/reset-ath79.c
@@ -15,7 +15,6 @@
struct ath79_reset {
struct reset_controller_dev rcdev;
- struct notifier_block restart_nb;
void __iomem *base;
spinlock_t lock;
};
@@ -72,11 +71,9 @@ static const struct reset_control_ops ath79_reset_ops = {
.status = ath79_reset_status,
};
-static int ath79_reset_restart_handler(struct notifier_block *nb,
- unsigned long action, void *data)
+static int ath79_reset_restart_handler(struct sys_off_data *data)
{
- struct ath79_reset *ath79_reset =
- container_of(nb, struct ath79_reset, restart_nb);
+ struct ath79_reset *ath79_reset = data->cb_data;
ath79_reset_assert(&ath79_reset->rcdev, FULL_CHIP_RESET);
@@ -108,10 +105,7 @@ static int ath79_reset_probe(struct platform_device *pdev)
if (err)
return err;
- ath79_reset->restart_nb.notifier_call = ath79_reset_restart_handler;
- ath79_reset->restart_nb.priority = 128;
-
- err = register_restart_handler(&ath79_reset->restart_nb);
+ err = devm_register_restart_handler(&pdev->dev, ath79_reset_restart_handler, ath79_reset);
if (err)
dev_warn(&pdev->dev, "Failed to register restart handler\n");
diff --git a/drivers/reset/reset-gpio.c b/drivers/reset/reset-gpio.c
index 0a1610d9e78a..26aa2c3a2e68 100644
--- a/drivers/reset/reset-gpio.c
+++ b/drivers/reset/reset-gpio.c
@@ -4,7 +4,7 @@
#include <linux/gpio/consumer.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
-#include <linux/of.h>
+#include <linux/property.h>
#include <linux/reset-controller.h>
struct reset_gpio_priv {
@@ -46,34 +46,22 @@ static const struct reset_control_ops reset_gpio_ops = {
.status = reset_gpio_status,
};
-static int reset_gpio_of_xlate(struct reset_controller_dev *rcdev,
- const struct of_phandle_args *reset_spec)
+static int reset_gpio_fwnode_xlate(struct reset_controller_dev *rcdev,
+ const struct fwnode_reference_args *reset_spec)
{
return reset_spec->args[0];
}
-static void reset_gpio_of_node_put(void *data)
-{
- of_node_put(data);
-}
-
static int reset_gpio_probe(struct auxiliary_device *adev,
const struct auxiliary_device_id *id)
{
struct device *dev = &adev->dev;
- struct of_phandle_args *platdata = dev_get_platdata(dev);
struct reset_gpio_priv *priv;
- int ret;
-
- if (!platdata)
- return -EINVAL;
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
- auxiliary_set_drvdata(adev, &priv->rc);
-
priv->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
if (IS_ERR(priv->reset))
return dev_err_probe(dev, PTR_ERR(priv->reset),
@@ -82,15 +70,10 @@ static int reset_gpio_probe(struct auxiliary_device *adev,
priv->rc.ops = &reset_gpio_ops;
priv->rc.owner = THIS_MODULE;
priv->rc.dev = dev;
- priv->rc.of_args = platdata;
- ret = devm_add_action_or_reset(dev, reset_gpio_of_node_put,
- priv->rc.of_node);
- if (ret)
- return ret;
/* Cells to match GPIO specifier, but it's not really used */
- priv->rc.of_reset_n_cells = 2;
- priv->rc.of_xlate = reset_gpio_of_xlate;
+ priv->rc.fwnode_reset_n_cells = 2;
+ priv->rc.fwnode_xlate = reset_gpio_fwnode_xlate;
priv->rc.nr_resets = 1;
return devm_reset_controller_register(dev, &priv->rc);
diff --git a/drivers/reset/reset-intel-gw.c b/drivers/reset/reset-intel-gw.c
index a5ce3350cb5e..0db64cc8a282 100644
--- a/drivers/reset/reset-intel-gw.c
+++ b/drivers/reset/reset-intel-gw.c
@@ -28,7 +28,6 @@ struct intel_reset_soc {
struct intel_reset_data {
struct reset_controller_dev rcdev;
- struct notifier_block restart_nb;
const struct intel_reset_soc *soc_data;
struct regmap *regmap;
struct device *dev;
@@ -153,12 +152,10 @@ static int intel_reset_xlate(struct reset_controller_dev *rcdev,
return id;
}
-static int intel_reset_restart_handler(struct notifier_block *nb,
- unsigned long action, void *data)
+static int intel_reset_restart_handler(struct sys_off_data *data)
{
- struct intel_reset_data *reset_data;
+ struct intel_reset_data *reset_data = data->cb_data;
- reset_data = container_of(nb, struct intel_reset_data, restart_nb);
intel_assert_device(&reset_data->rcdev, reset_data->reboot_id);
return NOTIFY_DONE;
@@ -215,9 +212,7 @@ static int intel_reset_probe(struct platform_device *pdev)
if (data->soc_data->legacy)
data->reboot_id |= FIELD_PREP(STAT_BIT_OFFSET_MASK, rb_id[2]);
- data->restart_nb.notifier_call = intel_reset_restart_handler;
- data->restart_nb.priority = 128;
- register_restart_handler(&data->restart_nb);
+ devm_register_restart_handler(&pdev->dev, intel_reset_restart_handler, data);
return 0;
}
diff --git a/drivers/reset/reset-lpc18xx.c b/drivers/reset/reset-lpc18xx.c
index e42b2f24a93d..8ac9f237e1ce 100644
--- a/drivers/reset/reset-lpc18xx.c
+++ b/drivers/reset/reset-lpc18xx.c
@@ -31,7 +31,6 @@
struct lpc18xx_rgu_data {
struct reset_controller_dev rcdev;
- struct notifier_block restart_nb;
struct clk *clk_delay;
struct clk *clk_reg;
void __iomem *base;
@@ -41,11 +40,9 @@ struct lpc18xx_rgu_data {
#define to_rgu_data(p) container_of(p, struct lpc18xx_rgu_data, rcdev)
-static int lpc18xx_rgu_restart(struct notifier_block *nb, unsigned long mode,
- void *cmd)
+static int lpc18xx_rgu_restart(struct sys_off_data *data)
{
- struct lpc18xx_rgu_data *rc = container_of(nb, struct lpc18xx_rgu_data,
- restart_nb);
+ struct lpc18xx_rgu_data *rc = data->cb_data;
writel(BIT(LPC18XX_RGU_CORE_RST), rc->base + LPC18XX_RGU_CTRL0);
mdelay(2000);
@@ -178,9 +175,8 @@ static int lpc18xx_rgu_probe(struct platform_device *pdev)
if (ret)
return dev_err_probe(&pdev->dev, ret, "unable to register device\n");
- rc->restart_nb.priority = 192,
- rc->restart_nb.notifier_call = lpc18xx_rgu_restart,
- ret = register_restart_handler(&rc->restart_nb);
+ ret = devm_register_sys_off_handler(&pdev->dev, SYS_OFF_MODE_RESTART, 192,
+ lpc18xx_rgu_restart, rc);
if (ret)
dev_warn(&pdev->dev, "failed to register restart handler\n");
diff --git a/drivers/reset/reset-ma35d1.c b/drivers/reset/reset-ma35d1.c
index 54e53863c98a..4ee901f00132 100644
--- a/drivers/reset/reset-ma35d1.c
+++ b/drivers/reset/reset-ma35d1.c
@@ -19,7 +19,6 @@
struct ma35d1_reset_data {
struct reset_controller_dev rcdev;
- struct notifier_block restart_handler;
void __iomem *base;
/* protect registers against concurrent read-modify-write */
spinlock_t lock;
@@ -125,10 +124,9 @@ static const struct {
[MA35D1_RESET_SSPCC] = {0x2C, 31}
};
-static int ma35d1_restart_handler(struct notifier_block *this, unsigned long mode, void *cmd)
+static int ma35d1_restart_handler(struct sys_off_data *sys_off_data)
{
- struct ma35d1_reset_data *data =
- container_of(this, struct ma35d1_reset_data, restart_handler);
+ struct ma35d1_reset_data *data = sys_off_data->cb_data;
u32 id = MA35D1_RESET_CHIP;
writel_relaxed(BIT(ma35d1_reset_map[id].bit),
@@ -213,11 +211,10 @@ static int ma35d1_reset_probe(struct platform_device *pdev)
reset_data->rcdev.nr_resets = MA35D1_RESET_COUNT;
reset_data->rcdev.ops = &ma35d1_reset_ops;
reset_data->rcdev.of_node = dev->of_node;
- reset_data->restart_handler.notifier_call = ma35d1_restart_handler;
- reset_data->restart_handler.priority = 192;
spin_lock_init(&reset_data->lock);
- err = register_restart_handler(&reset_data->restart_handler);
+ err = devm_register_sys_off_handler(dev, SYS_OFF_MODE_RESTART, 192,
+ ma35d1_restart_handler, reset_data);
if (err)
dev_warn(&pdev->dev, "failed to register restart handler\n");
diff --git a/drivers/reset/reset-npcm.c b/drivers/reset/reset-npcm.c
index 4070a4b6663f..a762d0215e76 100644
--- a/drivers/reset/reset-npcm.c
+++ b/drivers/reset/reset-npcm.c
@@ -89,7 +89,6 @@ static const struct npcm_reset_info npxm8xx_reset_info[] = {
struct npcm_rc_data {
struct reset_controller_dev rcdev;
- struct notifier_block restart_nb;
const struct npcm_reset_info *info;
struct regmap *gcr_regmap;
u32 sw_reset_number;
@@ -100,11 +99,9 @@ struct npcm_rc_data {
#define to_rc_data(p) container_of(p, struct npcm_rc_data, rcdev)
-static int npcm_rc_restart(struct notifier_block *nb, unsigned long mode,
- void *cmd)
+static int npcm_rc_restart(struct sys_off_data *data)
{
- struct npcm_rc_data *rc = container_of(nb, struct npcm_rc_data,
- restart_nb);
+ struct npcm_rc_data *rc = data->cb_data;
writel(NPCM_SWRST << rc->sw_reset_number, rc->base + NPCM_SWRSTR);
mdelay(1000);
@@ -472,9 +469,8 @@ static int npcm_rc_probe(struct platform_device *pdev)
if (!of_property_read_u32(pdev->dev.of_node, "nuvoton,sw-reset-number",
&rc->sw_reset_number)) {
if (rc->sw_reset_number && rc->sw_reset_number < 5) {
- rc->restart_nb.priority = 192;
- rc->restart_nb.notifier_call = npcm_rc_restart;
- ret = register_restart_handler(&rc->restart_nb);
+ ret = devm_register_sys_off_handler(&pdev->dev, SYS_OFF_MODE_RESTART, 192,
+ npcm_rc_restart, rc);
if (ret) {
dev_warn(&pdev->dev, "failed to register restart handler\n");
return ret;
diff --git a/drivers/reset/reset-rzv2h-usb2phy.c b/drivers/reset/reset-rzv2h-usb2phy.c
index ae643575b067..d96042e28cd5 100644
--- a/drivers/reset/reset-rzv2h-usb2phy.c
+++ b/drivers/reset/reset-rzv2h-usb2phy.c
@@ -5,42 +5,39 @@
* Copyright (C) 2025 Renesas Electronics Corporation
*/
-#include <linux/cleanup.h>
+#include <linux/auxiliary_bus.h>
#include <linux/delay.h>
+#include <linux/idr.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
#include <linux/reset.h>
#include <linux/reset-controller.h>
-struct rzv2h_usb2phy_regval {
- u16 reg;
- u16 val;
-};
+static DEFINE_IDA(auxiliary_ids);
struct rzv2h_usb2phy_reset_of_data {
- const struct rzv2h_usb2phy_regval *init_vals;
- unsigned int init_val_count;
+ const struct reg_sequence *init_seq;
+ unsigned int init_nseq;
+
+ const struct reg_sequence *assert_seq;
+ unsigned int assert_nseq;
+
+ const struct reg_sequence *deassert_seq;
+ unsigned int deassert_nseq;
u16 reset_reg;
- u16 reset_assert_val;
- u16 reset_deassert_val;
u16 reset_status_bits;
- u16 reset_release_val;
-
- u16 reset2_reg;
- u16 reset2_acquire_val;
- u16 reset2_release_val;
};
struct rzv2h_usb2phy_reset_priv {
const struct rzv2h_usb2phy_reset_of_data *data;
- void __iomem *base;
+ struct regmap *regmap;
struct device *dev;
struct reset_controller_dev rcdev;
- spinlock_t lock; /* protects register accesses */
};
static inline struct rzv2h_usb2phy_reset_priv
@@ -49,81 +46,31 @@ static inline struct rzv2h_usb2phy_reset_priv
return container_of(rcdev, struct rzv2h_usb2phy_reset_priv, rcdev);
}
-/* This function must be called only after pm_runtime_resume_and_get() has been called */
-static void rzv2h_usbphy_assert_helper(struct rzv2h_usb2phy_reset_priv *priv)
-{
- const struct rzv2h_usb2phy_reset_of_data *data = priv->data;
-
- scoped_guard(spinlock, &priv->lock) {
- writel(data->reset2_acquire_val, priv->base + data->reset2_reg);
- writel(data->reset_assert_val, priv->base + data->reset_reg);
- }
-
- usleep_range(11, 20);
-}
-
static int rzv2h_usbphy_reset_assert(struct reset_controller_dev *rcdev,
unsigned long id)
{
struct rzv2h_usb2phy_reset_priv *priv = rzv2h_usbphy_rcdev_to_priv(rcdev);
- struct device *dev = priv->dev;
- int ret;
-
- ret = pm_runtime_resume_and_get(dev);
- if (ret) {
- dev_err(dev, "pm_runtime_resume_and_get failed\n");
- return ret;
- }
-
- rzv2h_usbphy_assert_helper(priv);
- pm_runtime_put(dev);
-
- return 0;
+ return regmap_multi_reg_write(priv->regmap, priv->data->assert_seq,
+ priv->data->assert_nseq);
}
static int rzv2h_usbphy_reset_deassert(struct reset_controller_dev *rcdev,
unsigned long id)
{
struct rzv2h_usb2phy_reset_priv *priv = rzv2h_usbphy_rcdev_to_priv(rcdev);
- const struct rzv2h_usb2phy_reset_of_data *data = priv->data;
- struct device *dev = priv->dev;
- int ret;
-
- ret = pm_runtime_resume_and_get(dev);
- if (ret) {
- dev_err(dev, "pm_runtime_resume_and_get failed\n");
- return ret;
- }
- scoped_guard(spinlock, &priv->lock) {
- writel(data->reset_deassert_val, priv->base + data->reset_reg);
- writel(data->reset2_release_val, priv->base + data->reset2_reg);
- writel(data->reset_release_val, priv->base + data->reset_reg);
- }
-
- pm_runtime_put(dev);
-
- return 0;
+ return regmap_multi_reg_write(priv->regmap, priv->data->deassert_seq,
+ priv->data->deassert_nseq);
}
static int rzv2h_usbphy_reset_status(struct reset_controller_dev *rcdev,
unsigned long id)
{
struct rzv2h_usb2phy_reset_priv *priv = rzv2h_usbphy_rcdev_to_priv(rcdev);
- struct device *dev = priv->dev;
- int ret;
u32 reg;
- ret = pm_runtime_resume_and_get(dev);
- if (ret) {
- dev_err(dev, "pm_runtime_resume_and_get failed\n");
- return ret;
- }
-
- reg = readl(priv->base + priv->data->reset_reg);
-
- pm_runtime_put(dev);
+ regmap_read(priv->regmap, priv->data->reset_reg, &reg);
return (reg & priv->data->reset_status_bits) == priv->data->reset_status_bits;
}
@@ -141,12 +88,52 @@ static int rzv2h_usb2phy_reset_of_xlate(struct reset_controller_dev *rcdev,
return 0;
}
+static void rzv2h_usb2phy_reset_ida_free(void *data)
+{
+ struct auxiliary_device *adev = data;
+
+ ida_free(&auxiliary_ids, adev->id);
+}
+
+static int rzv2h_usb2phy_reset_mux_register(struct device *dev,
+ const char *mux_name)
+{
+ struct auxiliary_device *adev;
+ int id;
+
+ id = ida_alloc(&auxiliary_ids, GFP_KERNEL);
+ if (id < 0)
+ return id;
+
+ adev = __devm_auxiliary_device_create(dev, dev->driver->name,
+ mux_name, NULL, id);
+ if (!adev) {
+ ida_free(&auxiliary_ids, id);
+ return -ENOMEM;
+ }
+
+ return devm_add_action_or_reset(dev, rzv2h_usb2phy_reset_ida_free, adev);
+}
+
+static const struct regmap_config rzv2h_usb2phy_reset_regconf = {
+ .reg_bits = 32,
+ .val_bits = 32,
+ .reg_stride = 4,
+ .can_sleep = true,
+};
+
+static void rzv2h_usb2phy_reset_pm_runtime_put(void *data)
+{
+ pm_runtime_put(data);
+}
+
static int rzv2h_usb2phy_reset_probe(struct platform_device *pdev)
{
const struct rzv2h_usb2phy_reset_of_data *data;
struct rzv2h_usb2phy_reset_priv *priv;
struct device *dev = &pdev->dev;
struct reset_control *rstc;
+ void __iomem *base;
int error;
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
@@ -156,17 +143,19 @@ static int rzv2h_usb2phy_reset_probe(struct platform_device *pdev)
data = of_device_get_match_data(dev);
priv->data = data;
priv->dev = dev;
- priv->base = devm_platform_ioremap_resource(pdev, 0);
- if (IS_ERR(priv->base))
- return PTR_ERR(priv->base);
+ base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(base))
+ return PTR_ERR(base);
+
+ priv->regmap = devm_regmap_init_mmio(dev, base, &rzv2h_usb2phy_reset_regconf);
+ if (IS_ERR(priv->regmap))
+ return PTR_ERR(priv->regmap);
rstc = devm_reset_control_get_shared_deasserted(dev, NULL);
if (IS_ERR(rstc))
return dev_err_probe(dev, PTR_ERR(rstc),
"failed to get deasserted reset\n");
- spin_lock_init(&priv->lock);
-
error = devm_pm_runtime_enable(dev);
if (error)
return dev_err_probe(dev, error, "Failed to enable pm_runtime\n");
@@ -175,13 +164,14 @@ static int rzv2h_usb2phy_reset_probe(struct platform_device *pdev)
if (error)
return dev_err_probe(dev, error, "pm_runtime_resume_and_get failed\n");
- for (unsigned int i = 0; i < data->init_val_count; i++)
- writel(data->init_vals[i].val, priv->base + data->init_vals[i].reg);
-
- /* keep usb2phy in asserted state */
- rzv2h_usbphy_assert_helper(priv);
+ error = devm_add_action_or_reset(dev, rzv2h_usb2phy_reset_pm_runtime_put,
+ dev);
+ if (error)
+ return dev_err_probe(dev, error, "unable to register cleanup action\n");
- pm_runtime_put(dev);
+ error = regmap_multi_reg_write(priv->regmap, data->init_seq, data->init_nseq);
+ if (error)
+ return dev_err_probe(dev, error, "failed to initialize PHY registers\n");
priv->rcdev.ops = &rzv2h_usbphy_reset_ops;
priv->rcdev.of_reset_n_cells = 0;
@@ -190,30 +180,47 @@ static int rzv2h_usb2phy_reset_probe(struct platform_device *pdev)
priv->rcdev.of_node = dev->of_node;
priv->rcdev.dev = dev;
- return devm_reset_controller_register(dev, &priv->rcdev);
+ error = devm_reset_controller_register(dev, &priv->rcdev);
+ if (error)
+ return dev_err_probe(dev, error, "could not register reset controller\n");
+
+ error = rzv2h_usb2phy_reset_mux_register(dev, "vbenctl");
+ if (error)
+ return dev_err_probe(dev, error, "could not register aux mux\n");
+
+ return 0;
}
/*
* initialization values required to prepare the PHY to receive
* assert and deassert requests.
*/
-static const struct rzv2h_usb2phy_regval rzv2h_init_vals[] = {
- { .reg = 0xc10, .val = 0x67c },
- { .reg = 0xc14, .val = 0x1f },
- { .reg = 0x600, .val = 0x909 },
+static const struct reg_sequence rzv2h_init_seq[] = {
+ { .reg = 0xc10, .def = 0x67c },
+ { .reg = 0xc14, .def = 0x01f },
+ { .reg = 0x600, .def = 0x909 },
+};
+
+static const struct reg_sequence rzv2h_assert_seq[] = {
+ { .reg = 0xb04, .def = 0x303 },
+ { .reg = 0x000, .def = 0x206, .delay_us = 11 },
+};
+
+static const struct reg_sequence rzv2h_deassert_seq[] = {
+ { .reg = 0x000, .def = 0x200 },
+ { .reg = 0xb04, .def = 0x003 },
+ { .reg = 0x000, .def = 0x000 },
};
static const struct rzv2h_usb2phy_reset_of_data rzv2h_reset_of_data = {
- .init_vals = rzv2h_init_vals,
- .init_val_count = ARRAY_SIZE(rzv2h_init_vals),
+ .init_seq = rzv2h_init_seq,
+ .init_nseq = ARRAY_SIZE(rzv2h_init_seq),
+ .assert_seq = rzv2h_assert_seq,
+ .assert_nseq = ARRAY_SIZE(rzv2h_assert_seq),
+ .deassert_seq = rzv2h_deassert_seq,
+ .deassert_nseq = ARRAY_SIZE(rzv2h_deassert_seq),
.reset_reg = 0,
- .reset_assert_val = 0x206,
.reset_status_bits = BIT(2),
- .reset_deassert_val = 0x200,
- .reset_release_val = 0x0,
- .reset2_reg = 0xb04,
- .reset2_acquire_val = 0x303,
- .reset2_release_val = 0x3,
};
static const struct of_device_id rzv2h_usb2phy_reset_of_match[] = {
diff --git a/drivers/reset/reset-sky1.c b/drivers/reset/reset-sky1.c
new file mode 100644
index 000000000000..78e80a533c39
--- /dev/null
+++ b/drivers/reset/reset-sky1.c
@@ -0,0 +1,367 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ *
+ * CIX System Reset Controller (SRC) driver
+ *
+ * Author: Jerry Zhu <jerry.zhu@cixtech.com>
+ */
+
+#include <linux/delay.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/reset-controller.h>
+
+#include <dt-bindings/reset/cix,sky1-system-control.h>
+#include <dt-bindings/reset/cix,sky1-s5-system-control.h>
+
+#define SKY1_RESET_SLEEP_MIN_US 50
+#define SKY1_RESET_SLEEP_MAX_US 100
+
+struct sky1_src_signal {
+ unsigned int offset;
+ unsigned int bit;
+};
+
+struct sky1_src_variant {
+ const struct sky1_src_signal *signals;
+ unsigned int signals_num;
+};
+
+struct sky1_src {
+ struct reset_controller_dev rcdev;
+ const struct sky1_src_signal *signals;
+ struct regmap *regmap;
+};
+
+enum {
+ CSU_PM_RESET = 0x304,
+ SENSORFUSION_RESET = 0x308,
+ SENSORFUSION_NOC_RESET = 0x30c,
+ RESET_GROUP0_S0_DOMAIN_0 = 0x400,
+ RESET_GROUP0_S0_DOMAIN_1 = 0x404,
+ RESET_GROUP1_USB_PHYS = 0x408,
+ RESET_GROUP1_USB_CONTROLLERS = 0x40c,
+ RESET_GROUP0_RCSU = 0x800,
+ RESET_GROUP1_RCSU = 0x804,
+};
+
+static const struct sky1_src_signal sky1_src_signals[] = {
+ /* reset group1 for s0 domain modules */
+ [SKY1_CSU_PM_RESET_N] = { CSU_PM_RESET, BIT(0) },
+ [SKY1_SENSORFUSION_RESET_N] = { SENSORFUSION_RESET, BIT(0) },
+ [SKY1_SENSORFUSION_NOC_RESET_N] = { SENSORFUSION_NOC_RESET, BIT(0) },
+ [SKY1_DDRC_RESET_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(0) },
+ [SKY1_GIC_RESET_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(1) },
+ [SKY1_CI700_RESET_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(2) },
+ [SKY1_SYS_NI700_RESET_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(3) },
+ [SKY1_MM_NI700_RESET_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(4) },
+ [SKY1_PCIE_NI700_RESET_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(5) },
+ [SKY1_GPU_RESET_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(6) },
+ [SKY1_NPUTOP_RESET_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(7) },
+ [SKY1_NPUCORE0_RESET_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(8) },
+ [SKY1_NPUCORE1_RESET_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(9) },
+ [SKY1_NPUCORE2_RESET_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(10) },
+ [SKY1_VPU_RESET_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(11) },
+ [SKY1_ISP_SRESET_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(12) },
+ [SKY1_ISP_ARESET_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(13) },
+ [SKY1_ISP_HRESET_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(14) },
+ [SKY1_ISP_GDCRESET_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(15) },
+ [SKY1_DPU_RESET0_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(16) },
+ [SKY1_DPU_RESET1_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(17) },
+ [SKY1_DPU_RESET2_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(18) },
+ [SKY1_DPU_RESET3_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(19) },
+ [SKY1_DPU_RESET4_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(20) },
+ [SKY1_DP_RESET0_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(21) },
+ [SKY1_DP_RESET1_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(22) },
+ [SKY1_DP_RESET2_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(23) },
+ [SKY1_DP_RESET3_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(24) },
+ [SKY1_DP_RESET4_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(25) },
+ [SKY1_DP_PHY_RST_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(26) },
+
+ /* reset group1 for s0 domain modules */
+ [SKY1_AUDIO_HIFI5_RESET_N] = { RESET_GROUP0_S0_DOMAIN_1, BIT(0) },
+ [SKY1_AUDIO_HIFI5_NOC_RESET_N] = { RESET_GROUP0_S0_DOMAIN_1, BIT(1) },
+ [SKY1_CSIDPHY_PRST0_N] = { RESET_GROUP0_S0_DOMAIN_1, BIT(2) },
+ [SKY1_CSIDPHY_CMNRST0_N] = { RESET_GROUP0_S0_DOMAIN_1, BIT(3) },
+ [SKY1_CSI0_RST_N] = { RESET_GROUP0_S0_DOMAIN_1, BIT(4) },
+ [SKY1_CSIDPHY_PRST1_N] = { RESET_GROUP0_S0_DOMAIN_1, BIT(5) },
+ [SKY1_CSIDPHY_CMNRST1_N] = { RESET_GROUP0_S0_DOMAIN_1, BIT(6) },
+ [SKY1_CSI1_RST_N] = { RESET_GROUP0_S0_DOMAIN_1, BIT(7) },
+ [SKY1_CSI2_RST_N] = { RESET_GROUP0_S0_DOMAIN_1, BIT(8) },
+ [SKY1_CSI3_RST_N] = { RESET_GROUP0_S0_DOMAIN_1, BIT(9) },
+ [SKY1_CSIBRDGE0_RST_N] = { RESET_GROUP0_S0_DOMAIN_1, BIT(10) },
+ [SKY1_CSIBRDGE1_RST_N] = { RESET_GROUP0_S0_DOMAIN_1, BIT(11) },
+ [SKY1_CSIBRDGE2_RST_N] = { RESET_GROUP0_S0_DOMAIN_1, BIT(12) },
+ [SKY1_CSIBRDGE3_RST_N] = { RESET_GROUP0_S0_DOMAIN_1, BIT(13) },
+ [SKY1_GMAC0_RST_N] = { RESET_GROUP0_S0_DOMAIN_1, BIT(14) },
+ [SKY1_GMAC1_RST_N] = { RESET_GROUP0_S0_DOMAIN_1, BIT(15) },
+ [SKY1_PCIE0_RESET_N] = { RESET_GROUP0_S0_DOMAIN_1, BIT(16) },
+ [SKY1_PCIE1_RESET_N] = { RESET_GROUP0_S0_DOMAIN_1, BIT(17) },
+ [SKY1_PCIE2_RESET_N] = { RESET_GROUP0_S0_DOMAIN_1, BIT(18) },
+ [SKY1_PCIE3_RESET_N] = { RESET_GROUP0_S0_DOMAIN_1, BIT(19) },
+ [SKY1_PCIE4_RESET_N] = { RESET_GROUP0_S0_DOMAIN_1, BIT(20) },
+
+ /* reset group1 for usb phys */
+ [SKY1_USB_DP_PHY0_PRST_N] = { RESET_GROUP1_USB_PHYS, BIT(0) },
+ [SKY1_USB_DP_PHY1_PRST_N] = { RESET_GROUP1_USB_PHYS, BIT(1) },
+ [SKY1_USB_DP_PHY2_PRST_N] = { RESET_GROUP1_USB_PHYS, BIT(2) },
+ [SKY1_USB_DP_PHY3_PRST_N] = { RESET_GROUP1_USB_PHYS, BIT(3) },
+ [SKY1_USB_DP_PHY0_RST_N] = { RESET_GROUP1_USB_PHYS, BIT(4) },
+ [SKY1_USB_DP_PHY1_RST_N] = { RESET_GROUP1_USB_PHYS, BIT(5) },
+ [SKY1_USB_DP_PHY2_RST_N] = { RESET_GROUP1_USB_PHYS, BIT(6) },
+ [SKY1_USB_DP_PHY3_RST_N] = { RESET_GROUP1_USB_PHYS, BIT(7) },
+ [SKY1_USBPHY_SS_PST_N] = { RESET_GROUP1_USB_PHYS, BIT(8) },
+ [SKY1_USBPHY_SS_RST_N] = { RESET_GROUP1_USB_PHYS, BIT(9) },
+ [SKY1_USBPHY_HS0_PRST_N] = { RESET_GROUP1_USB_PHYS, BIT(10) },
+ [SKY1_USBPHY_HS1_PRST_N] = { RESET_GROUP1_USB_PHYS, BIT(11) },
+ [SKY1_USBPHY_HS2_PRST_N] = { RESET_GROUP1_USB_PHYS, BIT(12) },
+ [SKY1_USBPHY_HS3_PRST_N] = { RESET_GROUP1_USB_PHYS, BIT(13) },
+ [SKY1_USBPHY_HS4_PRST_N] = { RESET_GROUP1_USB_PHYS, BIT(14) },
+ [SKY1_USBPHY_HS5_PRST_N] = { RESET_GROUP1_USB_PHYS, BIT(15) },
+ [SKY1_USBPHY_HS6_PRST_N] = { RESET_GROUP1_USB_PHYS, BIT(16) },
+ [SKY1_USBPHY_HS7_PRST_N] = { RESET_GROUP1_USB_PHYS, BIT(17) },
+ [SKY1_USBPHY_HS8_PRST_N] = { RESET_GROUP1_USB_PHYS, BIT(18) },
+ [SKY1_USBPHY_HS9_PRST_N] = { RESET_GROUP1_USB_PHYS, BIT(19) },
+
+ /* reset group1 for usb controllers */
+ [SKY1_USBC_SS0_PRST_N] = { RESET_GROUP1_USB_CONTROLLERS, BIT(0) },
+ [SKY1_USBC_SS1_PRST_N] = { RESET_GROUP1_USB_CONTROLLERS, BIT(1) },
+ [SKY1_USBC_SS2_PRST_N] = { RESET_GROUP1_USB_CONTROLLERS, BIT(2) },
+ [SKY1_USBC_SS3_PRST_N] = { RESET_GROUP1_USB_CONTROLLERS, BIT(3) },
+ [SKY1_USBC_SS4_PRST_N] = { RESET_GROUP1_USB_CONTROLLERS, BIT(4) },
+ [SKY1_USBC_SS5_PRST_N] = { RESET_GROUP1_USB_CONTROLLERS, BIT(5) },
+ [SKY1_USBC_SS0_RST_N] = { RESET_GROUP1_USB_CONTROLLERS, BIT(6) },
+ [SKY1_USBC_SS1_RST_N] = { RESET_GROUP1_USB_CONTROLLERS, BIT(7) },
+ [SKY1_USBC_SS2_RST_N] = { RESET_GROUP1_USB_CONTROLLERS, BIT(8) },
+ [SKY1_USBC_SS3_RST_N] = { RESET_GROUP1_USB_CONTROLLERS, BIT(9) },
+ [SKY1_USBC_SS4_RST_N] = { RESET_GROUP1_USB_CONTROLLERS, BIT(10) },
+ [SKY1_USBC_SS5_RST_N] = { RESET_GROUP1_USB_CONTROLLERS, BIT(11) },
+ [SKY1_USBC_HS0_PRST_N] = { RESET_GROUP1_USB_CONTROLLERS, BIT(12) },
+ [SKY1_USBC_HS1_PRST_N] = { RESET_GROUP1_USB_CONTROLLERS, BIT(13) },
+ [SKY1_USBC_HS2_PRST_N] = { RESET_GROUP1_USB_CONTROLLERS, BIT(14) },
+ [SKY1_USBC_HS3_PRST_N] = { RESET_GROUP1_USB_CONTROLLERS, BIT(15) },
+ [SKY1_USBC_HS0_RST_N] = { RESET_GROUP1_USB_CONTROLLERS, BIT(16) },
+ [SKY1_USBC_HS1_RST_N] = { RESET_GROUP1_USB_CONTROLLERS, BIT(17) },
+ [SKY1_USBC_HS2_RST_N] = { RESET_GROUP1_USB_CONTROLLERS, BIT(18) },
+ [SKY1_USBC_HS3_RST_N] = { RESET_GROUP1_USB_CONTROLLERS, BIT(19) },
+
+ /* reset group0 for rcsu */
+ [SKY1_AUDIO_RCSU_RESET_N] = { RESET_GROUP0_RCSU, BIT(0) },
+ [SKY1_CI700_RCSU_RESET_N] = { RESET_GROUP0_RCSU, BIT(1) },
+ [SKY1_CSI_RCSU0_RESET_N] = { RESET_GROUP0_RCSU, BIT(2) },
+ [SKY1_CSI_RCSU1_RESET_N] = { RESET_GROUP0_RCSU, BIT(3) },
+ [SKY1_CSU_PM_RCSU_RESET_N] = { RESET_GROUP0_RCSU, BIT(4) },
+ [SKY1_DDR_BROADCAST_RCSU_RESET_N] = { RESET_GROUP0_RCSU, BIT(5) },
+ [SKY1_DDR_CTRL_RCSU_0_RESET_N] = { RESET_GROUP0_RCSU, BIT(6) },
+ [SKY1_DDR_CTRL_RCSU_1_RESET_N] = { RESET_GROUP0_RCSU, BIT(7) },
+ [SKY1_DDR_CTRL_RCSU_2_RESET_N] = { RESET_GROUP0_RCSU, BIT(8) },
+ [SKY1_DDR_CTRL_RCSU_3_RESET_N] = { RESET_GROUP0_RCSU, BIT(9) },
+ [SKY1_DDR_TZC400_RCSU_0_RESET_N] = { RESET_GROUP0_RCSU, BIT(10) },
+ [SKY1_DDR_TZC400_RCSU_1_RESET_N] = { RESET_GROUP0_RCSU, BIT(11) },
+ [SKY1_DDR_TZC400_RCSU_2_RESET_N] = { RESET_GROUP0_RCSU, BIT(12) },
+ [SKY1_DDR_TZC400_RCSU_3_RESET_N] = { RESET_GROUP0_RCSU, BIT(13) },
+ [SKY1_DP0_RCSU_RESET_N] = { RESET_GROUP0_RCSU, BIT(14) },
+ [SKY1_DP1_RCSU_RESET_N] = { RESET_GROUP0_RCSU, BIT(15) },
+ [SKY1_DP2_RCSU_RESET_N] = { RESET_GROUP0_RCSU, BIT(16) },
+ [SKY1_DP3_RCSU_RESET_N] = { RESET_GROUP0_RCSU, BIT(17) },
+ [SKY1_DP4_RCSU_RESET_N] = { RESET_GROUP0_RCSU, BIT(18) },
+ [SKY1_DPU0_RCSU_RESET_N] = { RESET_GROUP0_RCSU, BIT(19) },
+ [SKY1_DPU1_RCSU_RESET_N] = { RESET_GROUP0_RCSU, BIT(20) },
+ [SKY1_DPU2_RCSU_RESET_N] = { RESET_GROUP0_RCSU, BIT(21) },
+ [SKY1_DPU3_RCSU_RESET_N] = { RESET_GROUP0_RCSU, BIT(22) },
+ [SKY1_DPU4_RCSU_RESET_N] = { RESET_GROUP0_RCSU, BIT(23) },
+ [SKY1_DSU_RCSU_RESET_N] = { RESET_GROUP0_RCSU, BIT(24) },
+ [SKY1_FCH_RCSU_RESET_N] = { RESET_GROUP0_RCSU, BIT(25) },
+ [SKY1_GICD_RCSU_RESET_N] = { RESET_GROUP0_RCSU, BIT(26) },
+ [SKY1_GMAC_RCSU_RESET_N] = { RESET_GROUP0_RCSU, BIT(27) },
+ [SKY1_GPU_RCSU_RESET_N] = { RESET_GROUP0_RCSU, BIT(28) },
+ [SKY1_ISP_RCSU0_RESET_N] = { RESET_GROUP0_RCSU, BIT(29) },
+ [SKY1_ISP_RCSU1_RESET_N] = { RESET_GROUP0_RCSU, BIT(30) },
+ [SKY1_NI700_MMHUB_RCSU_RESET_N] = { RESET_GROUP0_RCSU, BIT(31) },
+
+ /* reset group1 for rcsu */
+ [SKY1_NPU_RCSU_RESET_N] = { RESET_GROUP1_RCSU, BIT(0) },
+ [SKY1_NI700_PCIE_RCSU_RESET_N] = { RESET_GROUP1_RCSU, BIT(1) },
+ [SKY1_PCIE_X421_RCSU_RESET_N] = { RESET_GROUP1_RCSU, BIT(2) },
+ [SKY1_PCIE_X8_RCSU_RESET_N] = { RESET_GROUP1_RCSU, BIT(3) },
+ [SKY1_SF_RCSU_RESET_N] = { RESET_GROUP1_RCSU, BIT(4) },
+ [SKY1_RCSU_SMMU_MMHUB_RESET_N] = { RESET_GROUP1_RCSU, BIT(5) },
+ [SKY1_RCSU_SMMU_PCIEHUB_RESET_N] = { RESET_GROUP1_RCSU, BIT(6) },
+ [SKY1_RCSU_SYSHUB_RESET_N] = { RESET_GROUP1_RCSU, BIT(7) },
+ [SKY1_NI700_SMN_RCSU_RESET_N] = { RESET_GROUP1_RCSU, BIT(8) },
+ [SKY1_NI700_SYSHUB_RCSU_RESET_N] = { RESET_GROUP1_RCSU, BIT(9) },
+ [SKY1_RCSU_USB2_HOST0_RESET_N] = { RESET_GROUP1_RCSU, BIT(10) },
+ [SKY1_RCSU_USB2_HOST1_RESET_N] = { RESET_GROUP1_RCSU, BIT(11) },
+ [SKY1_RCSU_USB2_HOST2_RESET_N] = { RESET_GROUP1_RCSU, BIT(12) },
+ [SKY1_RCSU_USB2_HOST3_RESET_N] = { RESET_GROUP1_RCSU, BIT(13) },
+ [SKY1_RCSU_USB3_TYPEA_DRD_RESET_N] = { RESET_GROUP1_RCSU, BIT(14) },
+ [SKY1_RCSU_USB3_TYPEC_DRD_RESET_N] = { RESET_GROUP1_RCSU, BIT(15) },
+ [SKY1_RCSU_USB3_TYPEC_HOST0_RESET_N] = { RESET_GROUP1_RCSU, BIT(16) },
+ [SKY1_RCSU_USB3_TYPEC_HOST1_RESET_N] = { RESET_GROUP1_RCSU, BIT(17) },
+ [SKY1_RCSU_USB3_TYPEC_HOST2_RESET_N] = { RESET_GROUP1_RCSU, BIT(18) },
+ [SKY1_VPU_RCSU_RESET_N] = { RESET_GROUP1_RCSU, BIT(19) },
+};
+
+static const struct sky1_src_variant variant_sky1 = {
+ .signals = sky1_src_signals,
+ .signals_num = ARRAY_SIZE(sky1_src_signals),
+};
+
+enum {
+ FCH_SW_RST_FUNC = 0x8,
+ FCH_SW_RST_BUS = 0xc,
+ FCH_SW_XSPI = 0x10,
+};
+
+static const struct sky1_src_signal sky1_src_fch_signals[] = {
+ /* resets for fch_sw_rst_func */
+ [SW_I3C0_RST_FUNC_G_N] = { FCH_SW_RST_FUNC, BIT(0) },
+ [SW_I3C0_RST_FUNC_I_N] = { FCH_SW_RST_FUNC, BIT(1) },
+ [SW_I3C1_RST_FUNC_G_N] = { FCH_SW_RST_FUNC, BIT(2) },
+ [SW_I3C1_RST_FUNC_I_N] = { FCH_SW_RST_FUNC, BIT(3) },
+ [SW_UART0_RST_FUNC_N] = { FCH_SW_RST_FUNC, BIT(4) },
+ [SW_UART1_RST_FUNC_N] = { FCH_SW_RST_FUNC, BIT(5) },
+ [SW_UART2_RST_FUNC_N] = { FCH_SW_RST_FUNC, BIT(6) },
+ [SW_UART3_RST_FUNC_N] = { FCH_SW_RST_FUNC, BIT(7) },
+ [SW_TIMER_RST_FUNC_N] = { FCH_SW_RST_FUNC, BIT(20) },
+
+ /* resets for fch_sw_rst_bus */
+ [SW_I3C0_RST_APB_N] = { FCH_SW_RST_BUS, BIT(0) },
+ [SW_I3C1_RST_APB_N] = { FCH_SW_RST_BUS, BIT(1) },
+ [SW_DMA_RST_AXI_N] = { FCH_SW_RST_BUS, BIT(2) },
+ [SW_UART0_RST_APB_N] = { FCH_SW_RST_BUS, BIT(4) },
+ [SW_UART1_RST_APB_N] = { FCH_SW_RST_BUS, BIT(5) },
+ [SW_UART2_RST_APB_N] = { FCH_SW_RST_BUS, BIT(6) },
+ [SW_UART3_RST_APB_N] = { FCH_SW_RST_BUS, BIT(7) },
+ [SW_SPI0_RST_APB_N] = { FCH_SW_RST_BUS, BIT(8) },
+ [SW_SPI1_RST_APB_N] = { FCH_SW_RST_BUS, BIT(9) },
+ [SW_I2C0_RST_APB_N] = { FCH_SW_RST_BUS, BIT(12) },
+ [SW_I2C1_RST_APB_N] = { FCH_SW_RST_BUS, BIT(13) },
+ [SW_I2C2_RST_APB_N] = { FCH_SW_RST_BUS, BIT(14) },
+ [SW_I2C3_RST_APB_N] = { FCH_SW_RST_BUS, BIT(15) },
+ [SW_I2C4_RST_APB_N] = { FCH_SW_RST_BUS, BIT(16) },
+ [SW_I2C5_RST_APB_N] = { FCH_SW_RST_BUS, BIT(17) },
+ [SW_I2C6_RST_APB_N] = { FCH_SW_RST_BUS, BIT(18) },
+ [SW_I2C7_RST_APB_N] = { FCH_SW_RST_BUS, BIT(19) },
+ [SW_GPIO_RST_APB_N] = { FCH_SW_RST_BUS, BIT(21) },
+
+ /* resets for fch_sw_xspi */
+ [SW_XSPI_REG_RST_N] = { FCH_SW_XSPI, BIT(0) },
+ [SW_XSPI_SYS_RST_N] = { FCH_SW_XSPI, BIT(1) },
+};
+
+static const struct sky1_src_variant variant_sky1_fch = {
+ .signals = sky1_src_fch_signals,
+ .signals_num = ARRAY_SIZE(sky1_src_fch_signals),
+};
+
+static struct sky1_src *to_sky1_src(struct reset_controller_dev *rcdev)
+{
+ return container_of(rcdev, struct sky1_src, rcdev);
+}
+
+static int sky1_reset_set(struct reset_controller_dev *rcdev,
+ unsigned long id, bool assert)
+{
+ struct sky1_src *sky1src = to_sky1_src(rcdev);
+ const struct sky1_src_signal *signal = &sky1src->signals[id];
+ unsigned int value = assert ? 0 : signal->bit;
+
+ return regmap_update_bits(sky1src->regmap,
+ signal->offset, signal->bit, value);
+}
+
+static int sky1_reset_assert(struct reset_controller_dev *rcdev,
+ unsigned long id)
+{
+ sky1_reset_set(rcdev, id, true);
+ usleep_range(SKY1_RESET_SLEEP_MIN_US,
+ SKY1_RESET_SLEEP_MAX_US);
+ return 0;
+}
+
+static int sky1_reset_deassert(struct reset_controller_dev *rcdev,
+ unsigned long id)
+{
+ sky1_reset_set(rcdev, id, false);
+ usleep_range(SKY1_RESET_SLEEP_MIN_US,
+ SKY1_RESET_SLEEP_MAX_US);
+ return 0;
+}
+
+static int sky1_reset(struct reset_controller_dev *rcdev,
+ unsigned long id)
+{
+ sky1_reset_assert(rcdev, id);
+ sky1_reset_deassert(rcdev, id);
+ return 0;
+}
+
+static int sky1_reset_status(struct reset_controller_dev *rcdev,
+ unsigned long id)
+{
+ unsigned int value = 0;
+ struct sky1_src *sky1src = to_sky1_src(rcdev);
+ const struct sky1_src_signal *signal = &sky1src->signals[id];
+
+ regmap_read(sky1src->regmap, signal->offset, &value);
+ return !(value & signal->bit);
+}
+
+static const struct reset_control_ops sky1_src_ops = {
+ .reset = sky1_reset,
+ .assert = sky1_reset_assert,
+ .deassert = sky1_reset_deassert,
+ .status = sky1_reset_status
+};
+
+static int sky1_reset_probe(struct platform_device *pdev)
+{
+ struct sky1_src *sky1src;
+ struct device *dev = &pdev->dev;
+ const struct sky1_src_variant *variant;
+
+ sky1src = devm_kzalloc(dev, sizeof(*sky1src), GFP_KERNEL);
+ if (!sky1src)
+ return -ENOMEM;
+
+ variant = of_device_get_match_data(dev);
+
+ sky1src->regmap = device_node_to_regmap(dev->of_node);
+ if (IS_ERR(sky1src->regmap)) {
+ return dev_err_probe(dev, PTR_ERR(sky1src->regmap),
+ "Unable to get sky1-src regmap");
+ }
+
+ sky1src->signals = variant->signals;
+ sky1src->rcdev.owner = THIS_MODULE;
+ sky1src->rcdev.nr_resets = variant->signals_num;
+ sky1src->rcdev.ops = &sky1_src_ops;
+ sky1src->rcdev.of_node = dev->of_node;
+ sky1src->rcdev.dev = dev;
+
+ return devm_reset_controller_register(dev, &sky1src->rcdev);
+}
+
+static const struct of_device_id sky1_sysreg_of_match[] = {
+ { .compatible = "cix,sky1-system-control", .data = &variant_sky1_fch},
+ { .compatible = "cix,sky1-s5-system-control", .data = &variant_sky1},
+ {},
+};
+MODULE_DEVICE_TABLE(of, sky1_sysreg_of_match);
+
+static struct platform_driver sky1_reset_driver = {
+ .probe = sky1_reset_probe,
+ .driver = {
+ .name = "cix,sky1-rst",
+ .of_match_table = sky1_sysreg_of_match,
+ },
+};
+module_platform_driver(sky1_reset_driver)
+
+MODULE_AUTHOR("Jerry Zhu <jerry.zhu@cixtech.com>");
+MODULE_DESCRIPTION("Cix Sky1 reset driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/reset/reset-sunplus.c b/drivers/reset/reset-sunplus.c
index df58decab64d..58b087433759 100644
--- a/drivers/reset/reset-sunplus.c
+++ b/drivers/reset/reset-sunplus.c
@@ -100,7 +100,6 @@ static const u32 sp_resets[] = {
struct sp_reset {
struct reset_controller_dev rcdev;
- struct notifier_block notifier;
void __iomem *base;
};
@@ -154,10 +153,9 @@ static const struct reset_control_ops sp_reset_ops = {
.status = sp_reset_status,
};
-static int sp_restart(struct notifier_block *nb, unsigned long mode,
- void *cmd)
+static int sp_restart(struct sys_off_data *data)
{
- struct sp_reset *reset = container_of(nb, struct sp_reset, notifier);
+ struct sp_reset *reset = data->cb_data;
sp_reset_assert(&reset->rcdev, 0);
sp_reset_deassert(&reset->rcdev, 0);
@@ -189,10 +187,8 @@ static int sp_reset_probe(struct platform_device *pdev)
if (ret)
return ret;
- reset->notifier.notifier_call = sp_restart;
- reset->notifier.priority = 192;
-
- return register_restart_handler(&reset->notifier);
+ return devm_register_sys_off_handler(&pdev->dev, SYS_OFF_MODE_RESTART,
+ 192, sp_restart, reset);
}
static const struct of_device_id sp_reset_dt_ids[] = {
diff --git a/drivers/reset/sti/reset-syscfg.c b/drivers/reset/sti/reset-syscfg.c
index 2324060b747c..38f78d78fa4f 100644
--- a/drivers/reset/sti/reset-syscfg.c
+++ b/drivers/reset/sti/reset-syscfg.c
@@ -41,7 +41,7 @@ struct syscfg_reset_channel {
struct syscfg_reset_controller {
struct reset_controller_dev rst;
bool active_low;
- struct syscfg_reset_channel *channels;
+ struct syscfg_reset_channel channels[];
};
#define to_syscfg_reset_controller(_rst) \
@@ -135,15 +135,10 @@ static int syscfg_reset_controller_register(struct device *dev,
struct syscfg_reset_controller *rc;
int i, err;
- rc = devm_kzalloc(dev, sizeof(*rc), GFP_KERNEL);
+ rc = devm_kzalloc(dev, struct_size(rc, channels, data->nr_channels), GFP_KERNEL);
if (!rc)
return -ENOMEM;
- rc->channels = devm_kcalloc(dev, data->nr_channels,
- sizeof(*rc->channels), GFP_KERNEL);
- if (!rc->channels)
- return -ENOMEM;
-
rc->rst.ops = &syscfg_reset_ops;
rc->rst.of_node = dev->of_node;
rc->rst.nr_resets = data->nr_channels;
diff --git a/drivers/soc/hisilicon/kunpeng_hccs.c b/drivers/soc/hisilicon/kunpeng_hccs.c
index 2af3bfda313e..0cc2953d59a5 100644
--- a/drivers/soc/hisilicon/kunpeng_hccs.c
+++ b/drivers/soc/hisilicon/kunpeng_hccs.c
@@ -961,7 +961,7 @@ static ssize_t link_fsm_show(struct kobject *kobj,
struct hccs_link_status link_status = {0};
const struct {
u8 link_fsm;
- char *str;
+ const char *str;
} link_fsm_map[] = {
{HCCS_PORT_RESET, "reset"},
{HCCS_PORT_SETUP, "setup"},
@@ -1621,8 +1621,7 @@ static void hccs_remove_topo_dirs(struct hccs_dev *hdev)
hccs_remove_misc_sysfs(hdev);
}
-static int hccs_create_hccs_dir(struct hccs_dev *hdev,
- struct hccs_die_info *die,
+static int hccs_create_hccs_dir(struct hccs_die_info *die,
struct hccs_port_info *port)
{
int ret;
@@ -1654,7 +1653,7 @@ static int hccs_create_die_dir(struct hccs_dev *hdev,
for (i = 0; i < die->port_num; i++) {
port = &die->ports[i];
- ret = hccs_create_hccs_dir(hdev, die, port);
+ ret = hccs_create_hccs_dir(die, port);
if (ret) {
dev_err(hdev->dev, "create hccs%u dir failed.\n",
port->port_id);
diff --git a/drivers/soc/microchip/Kconfig b/drivers/soc/microchip/Kconfig
index bcf554602561..af7946741bce 100644
--- a/drivers/soc/microchip/Kconfig
+++ b/drivers/soc/microchip/Kconfig
@@ -1,3 +1,14 @@
+config POLARFIRE_SOC_IRQ_MUX
+ bool "Microchip PolarFire SoC's GPIO IRQ Mux"
+ depends on ARCH_MICROCHIP
+ select REGMAP
+ select REGMAP_MMIO
+ default y
+ help
+ Support for the interrupt mux on Polarfire SoC. It sits between
+ the GPIO controllers and the PLIC, as only 41 interrupts are shared
+ between 3 GPIO controllers with a total of 70 interrupts.
+
config POLARFIRE_SOC_SYS_CTRL
tristate "Microchip PolarFire SoC (MPFS) system controller support"
depends on POLARFIRE_SOC_MAILBOX
diff --git a/drivers/soc/microchip/Makefile b/drivers/soc/microchip/Makefile
index 1a3a1594b089..55775db45ee7 100644
--- a/drivers/soc/microchip/Makefile
+++ b/drivers/soc/microchip/Makefile
@@ -1,2 +1,3 @@
+obj-$(CONFIG_POLARFIRE_SOC_IRQ_MUX) += mpfs-irqmux.o
obj-$(CONFIG_POLARFIRE_SOC_SYS_CTRL) += mpfs-sys-controller.o
obj-$(CONFIG_POLARFIRE_SOC_SYSCONS) += mpfs-control-scb.o mpfs-mss-top-sysreg.o
diff --git a/drivers/soc/microchip/mpfs-irqmux.c b/drivers/soc/microchip/mpfs-irqmux.c
new file mode 100644
index 000000000000..ae15e913e780
--- /dev/null
+++ b/drivers/soc/microchip/mpfs-irqmux.c
@@ -0,0 +1,181 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Largely copied from rzn1_irqmux.c
+ */
+
+#include <linux/bitmap.h>
+#include <linux/bitops.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#define MPFS_IRQMUX_CR 0x54
+#define MPFS_IRQMUX_NUM_CHILDREN 96
+#define MPFS_IRQMUX_NUM_DIRECT 38
+#define MPFS_IRQMUX_DIRECT_START 13
+#define MPFS_IRQMUX_DIRECT_END 50
+#define MPFS_IRQMUX_NONDIRECT_END 53
+
+static int mpfs_irqmux_is_direct_mode(struct device *dev,
+ const struct of_phandle_args *parent_args)
+{
+ if (parent_args->args_count != 1) {
+ dev_err(dev, "Invalid interrupt-map item\n");
+ return -EINVAL;
+ }
+
+ if (parent_args->args[0] < MPFS_IRQMUX_DIRECT_START ||
+ parent_args->args[0] > MPFS_IRQMUX_NONDIRECT_END) {
+ dev_err(dev, "Invalid interrupt %u\n", parent_args->args[0]);
+ return -EINVAL;
+ }
+
+ if (parent_args->args[0] > MPFS_IRQMUX_DIRECT_END)
+ return 0;
+
+ return 1;
+}
+
+static int mpfs_irqmux_probe(struct platform_device *pdev)
+{
+ DECLARE_BITMAP(child_done, MPFS_IRQMUX_NUM_CHILDREN) = {};
+ DECLARE_BITMAP(parent_done, MPFS_IRQMUX_NUM_DIRECT) = {};
+ struct device *dev = &pdev->dev;
+ struct device_node *np = dev->of_node;
+ struct of_imap_parser imap_parser;
+ struct of_imap_item imap_item;
+ struct regmap *regmap;
+ int ret, direct_mode, line, controller, gpio, parent_line;
+ u32 tmp, val = 0, old;
+
+ regmap = device_node_to_regmap(pdev->dev.parent->of_node);
+ if (IS_ERR(regmap))
+ return dev_err_probe(dev, PTR_ERR(regmap), "Failed to find syscon regmap\n");
+
+ /* We support only #interrupt-cells = <1> and #address-cells = <0> */
+ ret = of_property_read_u32(np, "#interrupt-cells", &tmp);
+ if (ret)
+ return ret;
+ if (tmp != 1)
+ return -EINVAL;
+
+ ret = of_property_read_u32(np, "#address-cells", &tmp);
+ if (ret)
+ return ret;
+ if (tmp != 0)
+ return -EINVAL;
+
+ ret = of_imap_parser_init(&imap_parser, np, &imap_item);
+ if (ret)
+ return ret;
+
+ for_each_of_imap_item(&imap_parser, &imap_item) {
+
+ direct_mode = mpfs_irqmux_is_direct_mode(dev, &imap_item.parent_args);
+ if (direct_mode < 0) {
+ of_node_put(imap_item.parent_args.np);
+ return direct_mode;
+ }
+
+ line = imap_item.child_imap[0];
+ gpio = line % 32;
+ controller = line / 32;
+
+ if (controller > 2) {
+ of_node_put(imap_item.parent_args.np);
+ dev_err(dev, "child interrupt number too large: %d\n", line);
+ return -EINVAL;
+ }
+
+ if (test_and_set_bit(line, child_done)) {
+ of_node_put(imap_item.parent_args.np);
+ dev_err(dev, "mux child line %d already defined in interrupt-map\n",
+ line);
+ return -EINVAL;
+ }
+
+ parent_line = imap_item.parent_args.args[0] - MPFS_IRQMUX_DIRECT_START;
+ if (direct_mode && test_and_set_bit(parent_line, parent_done)) {
+ of_node_put(imap_item.parent_args.np);
+ dev_err(dev, "mux parent line %d already defined in interrupt-map\n",
+ line);
+ return -EINVAL;
+ }
+
+ /*
+ * There are 41 interrupts assigned to GPIOs, of which 38 are "direct". Since the
+ * mux has 32 bits only, 6 of these exclusive/"direct" interrupts remain. These
+ * are used by GPIO controller 1's lines 18 to 23. Nothing needs to be done
+ * for these interrupts.
+ */
+ if (controller == 1 && gpio >= 18)
+ continue;
+
+ /*
+ * The mux has a single register, where bits 0 to 13 mux between GPIO controller
+ * 1's 14 GPIOs and GPIO controller 2's first 14 GPIOs. The remaining bits mux
+ * between the first 18 GPIOs of controller 1 and the last 18 GPIOS of
+ * controller 2. If a bit in the mux's control register is set, the
+ * corresponding interrupt line for GPIO controller 0 or 1 will be put in
+ * "non-direct" mode. If cleared, the "fabric" controller's will.
+ *
+ * Register layout:
+ * GPIO 1 interrupt line 17 | mux bit 31 | GPIO 2 interrupt line 31
+ * ... | ... | ...
+ * ... | ... | ...
+ * GPIO 1 interrupt line 0 | mux bit 14 | GPIO 2 interrupt line 14
+ * GPIO 0 interrupt line 13 | mux bit 13 | GPIO 2 interrupt line 13
+ * ... | ... | ...
+ * ... | ... | ...
+ * GPIO 0 interrupt line 0 | mux bit 0 | GPIO 2 interrupt line 0
+ *
+ * As the binding mandates 70 items, one for each GPIO line, there's no need to
+ * handle anything for GPIO controller 2, since the bit will be set for the
+ * corresponding line in GPIO controller 0 or 1.
+ */
+ if (controller == 2)
+ continue;
+
+ /*
+ * If in direct mode, the bit is cleared, nothing needs to be done as val is zero
+ * initialised and that's the direct mode setting for GPIO controller 0 and 1.
+ */
+ if (direct_mode)
+ continue;
+
+ if (controller == 0)
+ val |= 1U << gpio;
+ else
+ val |= 1U << (gpio + 14);
+ }
+
+ regmap_read(regmap, MPFS_IRQMUX_CR, &old);
+ regmap_write(regmap, MPFS_IRQMUX_CR, val);
+
+ if (val != old)
+ dev_info(dev, "firmware mux setting of 0x%x overwritten to 0x%x\n", old, val);
+
+ return 0;
+}
+
+static const struct of_device_id mpfs_irqmux_of_match[] = {
+ { .compatible = "microchip,mpfs-irqmux", },
+ { }
+};
+MODULE_DEVICE_TABLE(of, mpfs_irqmux_of_match);
+
+static struct platform_driver mpfs_irqmux_driver = {
+ .probe = mpfs_irqmux_probe,
+ .driver = {
+ .name = "mpfs_irqmux",
+ .of_match_table = mpfs_irqmux_of_match,
+ },
+};
+module_platform_driver(mpfs_irqmux_driver);
+
+MODULE_AUTHOR("Conor Dooley <conor.dooley@microchip.com>");
+MODULE_DESCRIPTION("Polarfire SoC interrupt mux driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/soc/microchip/mpfs-sys-controller.c b/drivers/soc/microchip/mpfs-sys-controller.c
index 10b2fc39da66..92d1142a59e6 100644
--- a/drivers/soc/microchip/mpfs-sys-controller.c
+++ b/drivers/soc/microchip/mpfs-sys-controller.c
@@ -36,6 +36,11 @@ struct mpfs_sys_controller {
struct kref consumers;
};
+struct mpfs_syscon_config {
+ unsigned int nb_subdevs;
+ struct platform_device *subdevs;
+};
+
int mpfs_blocking_transaction(struct mpfs_sys_controller *sys_controller, struct mpfs_mss_msg *msg)
{
unsigned long timeout = msecs_to_jiffies(MPFS_SYS_CTRL_TIMEOUT_MS);
@@ -110,25 +115,11 @@ struct mtd_info *mpfs_sys_controller_get_flash(struct mpfs_sys_controller *mpfs_
}
EXPORT_SYMBOL(mpfs_sys_controller_get_flash);
-static struct platform_device subdevs[] = {
- {
- .name = "mpfs-rng",
- .id = -1,
- },
- {
- .name = "mpfs-generic-service",
- .id = -1,
- },
- {
- .name = "mpfs-auto-update",
- .id = -1,
- },
-};
-
static int mpfs_sys_controller_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct mpfs_sys_controller *sys_controller;
+ struct mpfs_syscon_config *of_data;
struct device_node *np;
int i, ret;
@@ -165,11 +156,17 @@ no_flash:
platform_set_drvdata(pdev, sys_controller);
+ of_data = (struct mpfs_syscon_config *) device_get_match_data(dev);
+ if (!of_data) {
+ dev_err(dev, "Error getting match data\n");
+ return -EINVAL;
+ }
- for (i = 0; i < ARRAY_SIZE(subdevs); i++) {
- subdevs[i].dev.parent = dev;
- if (platform_device_register(&subdevs[i]))
- dev_warn(dev, "Error registering sub device %s\n", subdevs[i].name);
+ for (i = 0; i < of_data->nb_subdevs; i++) {
+ of_data->subdevs[i].dev.parent = dev;
+ if (platform_device_register(&of_data->subdevs[i]))
+ dev_warn(dev, "Error registering sub device %s\n",
+ of_data->subdevs[i].name);
}
dev_info(&pdev->dev, "Registered MPFS system controller\n");
@@ -188,8 +185,45 @@ static void mpfs_sys_controller_remove(struct platform_device *pdev)
mpfs_sys_controller_put(sys_controller);
}
+static struct platform_device mpfs_subdevs[] = {
+ {
+ .name = "mpfs-rng",
+ .id = -1,
+ },
+ {
+ .name = "mpfs-generic-service",
+ .id = -1,
+ },
+ {
+ .name = "mpfs-auto-update",
+ .id = -1,
+ },
+};
+
+static struct platform_device pic64gx_subdevs[] = {
+ {
+ .name = "mpfs-rng",
+ .id = -1,
+ },
+ {
+ .name = "mpfs-generic-service",
+ .id = -1,
+ },
+};
+
+static const struct mpfs_syscon_config mpfs_config = {
+ .nb_subdevs = ARRAY_SIZE(mpfs_subdevs),
+ .subdevs = mpfs_subdevs,
+};
+
+static const struct mpfs_syscon_config pic64gx_config = {
+ .nb_subdevs = ARRAY_SIZE(pic64gx_subdevs),
+ .subdevs = pic64gx_subdevs,
+};
+
static const struct of_device_id mpfs_sys_controller_of_match[] = {
- {.compatible = "microchip,mpfs-sys-controller", },
+ {.compatible = "microchip,mpfs-sys-controller", .data = &mpfs_config},
+ {.compatible = "microchip,pic64gx-sys-controller", .data = &pic64gx_config},
{},
};
MODULE_DEVICE_TABLE(of, mpfs_sys_controller_of_match);
diff --git a/drivers/soc/qcom/llcc-qcom.c b/drivers/soc/qcom/llcc-qcom.c
index ad5899d083f3..0161ceec8842 100644
--- a/drivers/soc/qcom/llcc-qcom.c
+++ b/drivers/soc/qcom/llcc-qcom.c
@@ -5,7 +5,6 @@
*/
#include <linux/bitfield.h>
-#include <linux/bitmap.h>
#include <linux/bitops.h>
#include <linux/cleanup.h>
#include <linux/device.h>
@@ -1782,6 +1781,94 @@ static const struct llcc_slice_config sc8280xp_data[] = {
},
};
+static const struct llcc_slice_config sdm670_data[] = {
+ {
+ .usecase_id = LLCC_CPUSS,
+ .slice_id = 1,
+ .max_cap = 512,
+ .priority = 1,
+ .bonus_ways = 0xf,
+ .res_ways = 0x0,
+ .cache_mode = 0,
+ .dis_cap_alloc = true,
+ .retain_on_pc = true,
+ .activate_on_init = true,
+ }, {
+ .usecase_id = LLCC_ROTATOR,
+ .slice_id = 4,
+ .max_cap = 384,
+ .priority = 2,
+ .fixed_size = true,
+ .bonus_ways = 0x0,
+ .res_ways = 0xe,
+ .cache_mode = 2,
+ .dis_cap_alloc = true,
+ .retain_on_pc = true,
+ }, {
+ .usecase_id = LLCC_VOICE,
+ .slice_id = 5,
+ .max_cap = 512,
+ .priority = 1,
+ .bonus_ways = 0xf,
+ .res_ways = 0x0,
+ .cache_mode = 0,
+ .dis_cap_alloc = true,
+ .retain_on_pc = true,
+ }, {
+ .usecase_id = LLCC_AUDIO,
+ .slice_id = 6,
+ .max_cap = 512,
+ .priority = 1,
+ .bonus_ways = 0xf,
+ .res_ways = 0x0,
+ .cache_mode = 0,
+ .dis_cap_alloc = true,
+ .retain_on_pc = true,
+ }, {
+ .usecase_id = LLCC_MDM,
+ .slice_id = 8,
+ .max_cap = 512,
+ .priority = 1,
+ .bonus_ways = 0xf,
+ .res_ways = 0x0,
+ .cache_mode = 0,
+ .dis_cap_alloc = true,
+ .retain_on_pc = true,
+ }, {
+ .usecase_id = LLCC_GPU,
+ .slice_id = 12,
+ .max_cap = 384,
+ .priority = 1,
+ .fixed_size = true,
+ .bonus_ways = 0x0,
+ .res_ways = 0x0,
+ .cache_mode = 0,
+ .dis_cap_alloc = true,
+ .retain_on_pc = true,
+ }, {
+ .usecase_id = LLCC_MMUHWT,
+ .slice_id = 13,
+ .max_cap = 512,
+ .priority = 1,
+ .bonus_ways = 0xf,
+ .res_ways = 0x0,
+ .cache_mode = 0,
+ .dis_cap_alloc = true,
+ .activate_on_init = true,
+ }, {
+ .usecase_id = LLCC_AUDHW,
+ .slice_id = 22,
+ .max_cap = 512,
+ .priority = 1,
+ .fixed_size = true,
+ .bonus_ways = 0xf,
+ .res_ways = 0x0,
+ .cache_mode = 0,
+ .dis_cap_alloc = true,
+ .retain_on_pc = true,
+ },
+};
+
static const struct llcc_slice_config sdm845_data[] = {{
.usecase_id = LLCC_CPUSS,
.slice_id = 1,
@@ -3943,7 +4030,7 @@ static const struct llcc_slice_config x1e80100_data[] = {
static const struct llcc_edac_reg_offset llcc_v1_edac_reg_offset = {
.trp_ecc_error_status0 = 0x20344,
.trp_ecc_error_status1 = 0x20348,
- .trp_ecc_sb_err_syn0 = 0x2304c,
+ .trp_ecc_sb_err_syn0 = 0x2034c,
.trp_ecc_db_err_syn0 = 0x20370,
.trp_ecc_error_cntr_clear = 0x20440,
.trp_interrupt_0_status = 0x20480,
@@ -4196,6 +4283,17 @@ static const struct qcom_llcc_config sc8280xp_cfg[] = {
},
};
+static const struct qcom_llcc_config sdm670_cfg[] = {
+ {
+ .sct_data = sdm670_data,
+ .size = ARRAY_SIZE(sdm670_data),
+ .skip_llcc_cfg = true,
+ .reg_offset = llcc_v1_reg_offset,
+ .edac_reg_offset = &llcc_v1_edac_reg_offset,
+ .no_edac = true,
+ },
+};
+
static const struct qcom_llcc_config sdm845_cfg[] = {
{
.sct_data = sdm845_data,
@@ -4364,6 +4462,11 @@ static const struct qcom_sct_config sc8280xp_cfgs = {
.num_config = ARRAY_SIZE(sc8280xp_cfg),
};
+static const struct qcom_sct_config sdm670_cfgs = {
+ .llcc_config = sdm670_cfg,
+ .num_config = ARRAY_SIZE(sdm670_cfg),
+};
+
static const struct qcom_sct_config sdm845_cfgs = {
.llcc_config = sdm845_cfg,
.num_config = ARRAY_SIZE(sdm845_cfg),
@@ -4431,8 +4534,7 @@ static struct llcc_drv_data *drv_data = (void *) -EPROBE_DEFER;
struct llcc_slice_desc *llcc_slice_getd(u32 uid)
{
const struct llcc_slice_config *cfg;
- struct llcc_slice_desc *desc;
- u32 sz, count;
+ u32 sz, i;
if (IS_ERR(drv_data))
return ERR_CAST(drv_data);
@@ -4440,21 +4542,14 @@ struct llcc_slice_desc *llcc_slice_getd(u32 uid)
cfg = drv_data->cfg;
sz = drv_data->cfg_size;
- for (count = 0; cfg && count < sz; count++, cfg++)
+ for (i = 0; cfg && i < sz; i++, cfg++)
if (cfg->usecase_id == uid)
break;
- if (count == sz || !cfg)
+ if (i == sz)
return ERR_PTR(-ENODEV);
- desc = kzalloc_obj(*desc);
- if (!desc)
- return ERR_PTR(-ENOMEM);
-
- desc->slice_id = cfg->slice_id;
- desc->slice_size = cfg->max_cap;
-
- return desc;
+ return &drv_data->desc[i];
}
EXPORT_SYMBOL_GPL(llcc_slice_getd);
@@ -4465,7 +4560,7 @@ EXPORT_SYMBOL_GPL(llcc_slice_getd);
void llcc_slice_putd(struct llcc_slice_desc *desc)
{
if (!IS_ERR_OR_NULL(desc))
- kfree(desc);
+ return;
}
EXPORT_SYMBOL_GPL(llcc_slice_putd);
@@ -4540,25 +4635,21 @@ int llcc_slice_activate(struct llcc_slice_desc *desc)
if (IS_ERR_OR_NULL(desc))
return -EINVAL;
- mutex_lock(&drv_data->lock);
- if (test_bit(desc->slice_id, drv_data->bitmap)) {
- mutex_unlock(&drv_data->lock);
+ guard(mutex)(&drv_data->lock);
+ /* Already active; try to take another reference. */
+ if (refcount_inc_not_zero(&desc->refcount))
return 0;
- }
act_ctrl_val = ACT_CTRL_OPCODE_ACTIVATE << ACT_CTRL_OPCODE_SHIFT;
-
ret = llcc_update_act_ctrl(desc->slice_id, act_ctrl_val,
DEACTIVATE);
- if (ret) {
- mutex_unlock(&drv_data->lock);
+ if (ret)
return ret;
- }
- __set_bit(desc->slice_id, drv_data->bitmap);
- mutex_unlock(&drv_data->lock);
+ /* Set first reference */
+ refcount_set(&desc->refcount, 1);
- return ret;
+ return 0;
}
EXPORT_SYMBOL_GPL(llcc_slice_activate);
@@ -4580,24 +4671,21 @@ int llcc_slice_deactivate(struct llcc_slice_desc *desc)
if (IS_ERR_OR_NULL(desc))
return -EINVAL;
- mutex_lock(&drv_data->lock);
- if (!test_bit(desc->slice_id, drv_data->bitmap)) {
- mutex_unlock(&drv_data->lock);
+ guard(mutex)(&drv_data->lock);
+ /* refcount > 1, drop one ref and we’re done. */
+ if (refcount_dec_not_one(&desc->refcount))
return 0;
- }
- act_ctrl_val = ACT_CTRL_OPCODE_DEACTIVATE << ACT_CTRL_OPCODE_SHIFT;
+ act_ctrl_val = ACT_CTRL_OPCODE_DEACTIVATE << ACT_CTRL_OPCODE_SHIFT;
ret = llcc_update_act_ctrl(desc->slice_id, act_ctrl_val,
ACTIVATE);
- if (ret) {
- mutex_unlock(&drv_data->lock);
+ if (ret)
return ret;
- }
- __clear_bit(desc->slice_id, drv_data->bitmap);
- mutex_unlock(&drv_data->lock);
+ /* Finalize: atomically transition 1 -> 0 */
+ WARN_ON_ONCE(!refcount_dec_if_one(&desc->refcount));
- return ret;
+ return 0;
}
EXPORT_SYMBOL_GPL(llcc_slice_deactivate);
@@ -4638,7 +4726,7 @@ static int _qcom_llcc_cfg_program(const struct llcc_slice_config *config,
u32 attr1_val;
u32 attr0_val;
u32 max_cap_cacheline;
- struct llcc_slice_desc desc;
+ struct llcc_slice_desc *desc;
attr1_val = config->cache_mode;
attr1_val |= config->probe_target_ways << ATTR1_PROBE_TARGET_WAYS_SHIFT;
@@ -4787,8 +4875,11 @@ static int _qcom_llcc_cfg_program(const struct llcc_slice_config *config,
}
if (config->activate_on_init) {
- desc.slice_id = config->slice_id;
- ret = llcc_slice_activate(&desc);
+ desc = llcc_slice_getd(config->usecase_id);
+ if (IS_ERR(desc))
+ return PTR_ERR(desc);
+
+ ret = llcc_slice_activate(desc);
}
return ret;
@@ -5101,18 +5192,18 @@ static int qcom_llcc_probe(struct platform_device *pdev)
llcc_cfg = cfg->sct_data;
sz = cfg->size;
-
- for (i = 0; i < sz; i++)
- if (llcc_cfg[i].slice_id > drv_data->max_slices)
- drv_data->max_slices = llcc_cfg[i].slice_id;
-
- drv_data->bitmap = devm_bitmap_zalloc(dev, drv_data->max_slices,
- GFP_KERNEL);
- if (!drv_data->bitmap) {
+ drv_data->desc = devm_kcalloc(dev, sz, sizeof(struct llcc_slice_desc), GFP_KERNEL);
+ if (!drv_data->desc) {
ret = -ENOMEM;
goto err;
}
+ for (i = 0; i < sz; i++) {
+ drv_data->desc[i].slice_id = llcc_cfg[i].slice_id;
+ drv_data->desc[i].slice_size = llcc_cfg[i].max_cap;
+ refcount_set(&drv_data->desc[i].refcount, 0);
+ }
+
drv_data->cfg = llcc_cfg;
drv_data->cfg_size = sz;
drv_data->edac_reg_offset = cfg->edac_reg_offset;
@@ -5160,6 +5251,7 @@ static const struct of_device_id qcom_llcc_of_match[] = {
{ .compatible = "qcom,sc7280-llcc", .data = &sc7280_cfgs },
{ .compatible = "qcom,sc8180x-llcc", .data = &sc8180x_cfgs },
{ .compatible = "qcom,sc8280xp-llcc", .data = &sc8280xp_cfgs },
+ { .compatible = "qcom,sdm670-llcc", .data = &sdm670_cfgs },
{ .compatible = "qcom,sdm845-llcc", .data = &sdm845_cfgs },
{ .compatible = "qcom,sm6350-llcc", .data = &sm6350_cfgs },
{ .compatible = "qcom,sm7150-llcc", .data = &sm7150_cfgs },
diff --git a/drivers/soc/qcom/ocmem.c b/drivers/soc/qcom/ocmem.c
index 6a23f18b0281..96ca0b87bfc4 100644
--- a/drivers/soc/qcom/ocmem.c
+++ b/drivers/soc/qcom/ocmem.c
@@ -196,17 +196,16 @@ struct ocmem *of_get_ocmem(struct device *dev)
}
pdev = of_find_device_by_node(devnode->parent);
- if (!pdev) {
- dev_err(dev, "Cannot find device node %s\n", devnode->name);
- return ERR_PTR(-EPROBE_DEFER);
- }
+ if (!pdev)
+ return dev_err_ptr_probe(dev, -EPROBE_DEFER,
+ "Cannot find device node %s\n",
+ devnode->name);
ocmem = platform_get_drvdata(pdev);
put_device(&pdev->dev);
- if (!ocmem) {
- dev_err(dev, "Cannot get ocmem\n");
- return ERR_PTR(-ENODEV);
- }
+ if (!ocmem)
+ return dev_err_ptr_probe(dev, -EPROBE_DEFER, "Cannot get ocmem\n");
+
return ocmem;
}
EXPORT_SYMBOL_GPL(of_get_ocmem);
@@ -308,7 +307,7 @@ static int ocmem_dev_probe(struct platform_device *pdev)
ocmem->dev = dev;
ocmem->config = device_get_match_data(dev);
- ocmem->core_clk = devm_clk_get(dev, "core");
+ ocmem->core_clk = devm_clk_get_optional(dev, "core");
if (IS_ERR(ocmem->core_clk))
return dev_err_probe(dev, PTR_ERR(ocmem->core_clk),
"Unable to get core clock\n");
diff --git a/drivers/soc/qcom/pdr_interface.c b/drivers/soc/qcom/pdr_interface.c
index 72259f489075..6d879e1540b0 100644
--- a/drivers/soc/qcom/pdr_interface.c
+++ b/drivers/soc/qcom/pdr_interface.c
@@ -523,7 +523,7 @@ struct pdr_service *pdr_add_lookup(struct pdr_handle *pdr,
if (!pds)
return ERR_PTR(-ENOMEM);
- pds->service = SERVREG_NOTIFIER_SERVICE;
+ pds->service = QMI_SERVICE_ID_SERVREG_NOTIF;
strscpy(pds->service_name, service_name, sizeof(pds->service_name));
strscpy(pds->service_path, service_path, sizeof(pds->service_path));
pds->need_locator_lookup = true;
@@ -678,7 +678,7 @@ struct pdr_handle *pdr_handle_alloc(void (*status)(int state,
if (ret < 0)
goto destroy_indack;
- ret = qmi_add_lookup(&pdr->locator_hdl, SERVREG_LOCATOR_SERVICE, 1, 1);
+ ret = qmi_add_lookup(&pdr->locator_hdl, QMI_SERVICE_ID_SERVREG_LOC, 1, 1);
if (ret < 0)
goto release_qmi_handle;
diff --git a/drivers/soc/qcom/pdr_internal.h b/drivers/soc/qcom/pdr_internal.h
index 047c0160b617..d867e9b5e973 100644
--- a/drivers/soc/qcom/pdr_internal.h
+++ b/drivers/soc/qcom/pdr_internal.h
@@ -4,9 +4,6 @@
#include <linux/soc/qcom/pdr.h>
-#define SERVREG_LOCATOR_SERVICE 0x40
-#define SERVREG_NOTIFIER_SERVICE 0x42
-
#define SERVREG_REGISTER_LISTENER_REQ 0x20
#define SERVREG_GET_DOMAIN_LIST_REQ 0x21
#define SERVREG_STATE_UPDATED_IND_ID 0x22
diff --git a/drivers/soc/qcom/pmic_glink.c b/drivers/soc/qcom/pmic_glink.c
index 627f96ca322e..3042261578aa 100644
--- a/drivers/soc/qcom/pmic_glink.c
+++ b/drivers/soc/qcom/pmic_glink.c
@@ -23,13 +23,19 @@ enum {
PMIC_GLINK_CLIENT_UCSI,
};
+struct pmic_glink_data {
+ unsigned long client_mask;
+ const char *charger_pdr_service_name;
+ const char *charger_pdr_service_path;
+};
+
struct pmic_glink {
struct device *dev;
struct pdr_handle *pdr;
struct rpmsg_endpoint *ept;
- unsigned long client_mask;
+ const struct pmic_glink_data *data;
struct auxiliary_device altmode_aux;
struct auxiliary_device ps_aux;
@@ -292,7 +298,6 @@ static struct rpmsg_driver pmic_glink_rpmsg_driver = {
static int pmic_glink_probe(struct platform_device *pdev)
{
- const unsigned long *match_data;
struct pdr_service *service;
struct pmic_glink *pg;
int ret;
@@ -309,12 +314,10 @@ static int pmic_glink_probe(struct platform_device *pdev)
spin_lock_init(&pg->client_lock);
mutex_init(&pg->state_lock);
- match_data = (unsigned long *)of_device_get_match_data(&pdev->dev);
- if (!match_data)
+ pg->data = of_device_get_match_data(&pdev->dev);
+ if (!pg->data)
return -EINVAL;
- pg->client_mask = *match_data;
-
pg->pdr = pdr_handle_alloc(pmic_glink_pdr_callback, pg);
if (IS_ERR(pg->pdr)) {
ret = dev_err_probe(&pdev->dev, PTR_ERR(pg->pdr),
@@ -322,27 +325,30 @@ static int pmic_glink_probe(struct platform_device *pdev)
return ret;
}
- if (pg->client_mask & BIT(PMIC_GLINK_CLIENT_UCSI)) {
+ if (pg->data->client_mask & BIT(PMIC_GLINK_CLIENT_UCSI)) {
ret = pmic_glink_add_aux_device(pg, &pg->ucsi_aux, "ucsi");
if (ret)
goto out_release_pdr_handle;
}
- if (pg->client_mask & BIT(PMIC_GLINK_CLIENT_ALTMODE)) {
+ if (pg->data->client_mask & BIT(PMIC_GLINK_CLIENT_ALTMODE)) {
ret = pmic_glink_add_aux_device(pg, &pg->altmode_aux, "altmode");
if (ret)
goto out_release_ucsi_aux;
}
- if (pg->client_mask & BIT(PMIC_GLINK_CLIENT_BATT)) {
+ if (pg->data->client_mask & BIT(PMIC_GLINK_CLIENT_BATT)) {
ret = pmic_glink_add_aux_device(pg, &pg->ps_aux, "power-supply");
if (ret)
goto out_release_altmode_aux;
}
- service = pdr_add_lookup(pg->pdr, "tms/servreg", "msm/adsp/charger_pd");
- if (IS_ERR(service)) {
- ret = dev_err_probe(&pdev->dev, PTR_ERR(service),
- "failed adding pdr lookup for charger_pd\n");
- goto out_release_aux_devices;
+ if (pg->data->charger_pdr_service_name && pg->data->charger_pdr_service_path) {
+ service = pdr_add_lookup(pg->pdr, pg->data->charger_pdr_service_name,
+ pg->data->charger_pdr_service_path);
+ if (IS_ERR(service)) {
+ ret = dev_err_probe(&pdev->dev, PTR_ERR(service),
+ "failed adding pdr lookup for charger_pd\n");
+ goto out_release_aux_devices;
+ }
}
mutex_lock(&__pmic_glink_lock);
@@ -352,13 +358,13 @@ static int pmic_glink_probe(struct platform_device *pdev)
return 0;
out_release_aux_devices:
- if (pg->client_mask & BIT(PMIC_GLINK_CLIENT_BATT))
+ if (pg->data->client_mask & BIT(PMIC_GLINK_CLIENT_BATT))
pmic_glink_del_aux_device(pg, &pg->ps_aux);
out_release_altmode_aux:
- if (pg->client_mask & BIT(PMIC_GLINK_CLIENT_ALTMODE))
+ if (pg->data->client_mask & BIT(PMIC_GLINK_CLIENT_ALTMODE))
pmic_glink_del_aux_device(pg, &pg->altmode_aux);
out_release_ucsi_aux:
- if (pg->client_mask & BIT(PMIC_GLINK_CLIENT_UCSI))
+ if (pg->data->client_mask & BIT(PMIC_GLINK_CLIENT_UCSI))
pmic_glink_del_aux_device(pg, &pg->ucsi_aux);
out_release_pdr_handle:
pdr_handle_release(pg->pdr);
@@ -372,23 +378,35 @@ static void pmic_glink_remove(struct platform_device *pdev)
pdr_handle_release(pg->pdr);
- if (pg->client_mask & BIT(PMIC_GLINK_CLIENT_BATT))
+ if (pg->data->client_mask & BIT(PMIC_GLINK_CLIENT_BATT))
pmic_glink_del_aux_device(pg, &pg->ps_aux);
- if (pg->client_mask & BIT(PMIC_GLINK_CLIENT_ALTMODE))
+ if (pg->data->client_mask & BIT(PMIC_GLINK_CLIENT_ALTMODE))
pmic_glink_del_aux_device(pg, &pg->altmode_aux);
- if (pg->client_mask & BIT(PMIC_GLINK_CLIENT_UCSI))
+ if (pg->data->client_mask & BIT(PMIC_GLINK_CLIENT_UCSI))
pmic_glink_del_aux_device(pg, &pg->ucsi_aux);
guard(mutex)(&__pmic_glink_lock);
__pmic_glink = NULL;
}
-static const unsigned long pmic_glink_sm8450_client_mask = BIT(PMIC_GLINK_CLIENT_BATT) |
- BIT(PMIC_GLINK_CLIENT_ALTMODE) |
- BIT(PMIC_GLINK_CLIENT_UCSI);
+static const struct pmic_glink_data pmic_glink_adsp_data = {
+ .client_mask = BIT(PMIC_GLINK_CLIENT_BATT) |
+ BIT(PMIC_GLINK_CLIENT_ALTMODE) |
+ BIT(PMIC_GLINK_CLIENT_UCSI),
+ .charger_pdr_service_name = "tms/servreg",
+ .charger_pdr_service_path = "msm/adsp/charger_pd",
+};
+
+static const struct pmic_glink_data pmic_glink_soccp_data = {
+ .client_mask = BIT(PMIC_GLINK_CLIENT_BATT) |
+ BIT(PMIC_GLINK_CLIENT_ALTMODE) |
+ BIT(PMIC_GLINK_CLIENT_UCSI),
+};
static const struct of_device_id pmic_glink_of_match[] = {
- { .compatible = "qcom,pmic-glink", .data = &pmic_glink_sm8450_client_mask },
+ { .compatible = "qcom,glymur-pmic-glink", .data = &pmic_glink_soccp_data },
+ { .compatible = "qcom,kaanapali-pmic-glink", .data = &pmic_glink_soccp_data },
+ { .compatible = "qcom,pmic-glink", .data = &pmic_glink_adsp_data },
{}
};
MODULE_DEVICE_TABLE(of, pmic_glink_of_match);
diff --git a/drivers/soc/qcom/qcom_aoss.c b/drivers/soc/qcom/qcom_aoss.c
index a543ab9bee6c..c255662b8fc3 100644
--- a/drivers/soc/qcom/qcom_aoss.c
+++ b/drivers/soc/qcom/qcom_aoss.c
@@ -355,7 +355,7 @@ static int qmp_cdev_set_cur_state(struct thermal_cooling_device *cdev,
/* Normalize state */
cdev_state = !!state;
- if (qmp_cdev->state == state)
+ if (qmp_cdev->state == cdev_state)
return 0;
ret = qmp_send(qmp_cdev->qmp, "{class: volt_flr, event:zero_temp, res:%s, value:%s}",
diff --git a/drivers/soc/qcom/qcom_pd_mapper.c b/drivers/soc/qcom/qcom_pd_mapper.c
index dc10bc859ff4..bb99f003844b 100644
--- a/drivers/soc/qcom/qcom_pd_mapper.c
+++ b/drivers/soc/qcom/qcom_pd_mapper.c
@@ -360,6 +360,14 @@ static const struct qcom_pdm_domain_data mpss_wlan_pd = {
},
};
+static const struct qcom_pdm_domain_data *glymur_domains[] = {
+ &adsp_audio_pd,
+ &adsp_root_pd,
+ &adsp_sensor_pd,
+ &cdsp_root_pd,
+ NULL,
+};
+
static const struct qcom_pdm_domain_data *kaanapali_domains[] = {
&adsp_audio_pd,
&adsp_root_pd,
@@ -401,6 +409,16 @@ static const struct qcom_pdm_domain_data *qcs404_domains[] = {
NULL,
};
+static const struct qcom_pdm_domain_data *qcs615_domains[] = {
+ &adsp_audio_pd,
+ &adsp_root_pd,
+ &adsp_sensor_pd,
+ &cdsp_root_pd,
+ &mpss_root_pd,
+ &mpss_wlan_pd,
+ NULL,
+};
+
static const struct qcom_pdm_domain_data *sc7180_domains[] = {
&adsp_audio_pd,
&adsp_root_pd_pdr,
@@ -560,8 +578,12 @@ static const struct of_device_id qcom_pdm_domains[] __maybe_unused = {
{ .compatible = "qcom,apq8064", .data = NULL, },
{ .compatible = "qcom,apq8074", .data = NULL, },
{ .compatible = "qcom,apq8084", .data = NULL, },
+ { .compatible = "qcom,eliza", .data = sm8550_domains, },
{ .compatible = "qcom,apq8096", .data = msm8996_domains, },
+ { .compatible = "qcom,glymur", .data = glymur_domains, },
{ .compatible = "qcom,kaanapali", .data = kaanapali_domains, },
+ { .compatible = "qcom,mahua", .data = glymur_domains, },
+ { .compatible = "qcom,milos", .data = sm8550_domains, },
{ .compatible = "qcom,msm8226", .data = NULL, },
{ .compatible = "qcom,msm8909", .data = NULL, },
{ .compatible = "qcom,msm8916", .data = NULL, },
@@ -572,6 +594,7 @@ static const struct of_device_id qcom_pdm_domains[] __maybe_unused = {
{ .compatible = "qcom,qcm2290", .data = qcm2290_domains, },
{ .compatible = "qcom,qcm6490", .data = sc7280_domains, },
{ .compatible = "qcom,qcs404", .data = qcs404_domains, },
+ { .compatible = "qcom,qcs615", .data = qcs615_domains, },
{ .compatible = "qcom,sc7180", .data = sc7180_domains, },
{ .compatible = "qcom,sc7280", .data = sc7280_domains, },
{ .compatible = "qcom,sc8180x", .data = sc8180x_domains, },
@@ -615,15 +638,9 @@ static struct qcom_pdm_data *qcom_pdm_start(void)
const struct qcom_pdm_domain_data * const *domains;
const struct of_device_id *match;
struct qcom_pdm_data *data;
- struct device_node *root;
int ret, i;
- root = of_find_node_by_path("/");
- if (!root)
- return ERR_PTR(-ENODEV);
-
- match = of_match_node(qcom_pdm_domains, root);
- of_node_put(root);
+ match = of_match_node(qcom_pdm_domains, of_root);
if (!match) {
pr_notice("PDM: no support for the platform, userspace daemon might be required.\n");
return ERR_PTR(-ENODEV);
@@ -656,7 +673,7 @@ static struct qcom_pdm_data *qcom_pdm_start(void)
goto err_stop;
}
- ret = qmi_add_server(&data->handle, SERVREG_LOCATOR_SERVICE,
+ ret = qmi_add_server(&data->handle, QMI_SERVICE_ID_SERVREG_LOC,
SERVREG_QMI_VERSION, SERVREG_QMI_INSTANCE);
if (ret) {
pr_err("PDM: error adding server %d\n", ret);
diff --git a/drivers/soc/qcom/smp2p.c b/drivers/soc/qcom/smp2p.c
index cb515c2340c1..af0ceeaf6e07 100644
--- a/drivers/soc/qcom/smp2p.c
+++ b/drivers/soc/qcom/smp2p.c
@@ -36,6 +36,10 @@
* The driver uses the Linux GPIO and interrupt framework to expose a virtual
* GPIO for each outbound entry and a virtual interrupt controller for each
* inbound entry.
+ *
+ * V2 of SMP2P allows remote processors to write to outbound smp2p items before
+ * the full smp2p connection is negotiated. This is important for processors
+ * started before linux runs.
*/
#define SMP2P_MAX_ENTRY 16
@@ -47,11 +51,12 @@
#define SMP2P_MAGIC 0x504d5324
#define SMP2P_ALL_FEATURES SMP2P_FEATURE_SSR_ACK
+#define MAX_VERSION 2
/**
* struct smp2p_smem_item - in memory communication structure
* @magic: magic number
- * @version: version - must be 1
+ * @version: version
* @features: features flag - currently unused
* @local_pid: processor id of sending end
* @remote_pid: processor id of receiving end
@@ -180,14 +185,22 @@ static void qcom_smp2p_kick(struct qcom_smp2p *smp2p)
static bool qcom_smp2p_check_ssr(struct qcom_smp2p *smp2p)
{
struct smp2p_smem_item *in = smp2p->in;
+ struct smp2p_entry *entry;
+ bool restart_done;
bool restart;
if (!smp2p->ssr_ack_enabled)
return false;
- restart = in->flags & BIT(SMP2P_FLAGS_RESTART_DONE_BIT);
+ restart_done = in->flags & BIT(SMP2P_FLAGS_RESTART_DONE_BIT);
+ restart = restart_done != smp2p->ssr_ack;
+ list_for_each_entry(entry, &smp2p->inbound, node) {
+ if (!entry->value)
+ continue;
+ entry->last_value = 0;
+ }
- return restart != smp2p->ssr_ack;
+ return restart;
}
static void qcom_smp2p_do_ssr_ack(struct qcom_smp2p *smp2p)
@@ -219,7 +232,57 @@ static void qcom_smp2p_negotiate(struct qcom_smp2p *smp2p)
smp2p->negotiation_done = true;
trace_smp2p_negotiate(smp2p->dev, out->features);
+ } else if (in->version && in->version < out->version) {
+ out->version = in->version;
+ qcom_smp2p_kick(smp2p);
+ }
+}
+
+static int qcom_smp2p_in_version(struct qcom_smp2p *smp2p)
+{
+ unsigned int smem_id = smp2p->smem_items[SMP2P_INBOUND];
+ unsigned int pid = smp2p->remote_pid;
+ struct smp2p_smem_item *in;
+ size_t size;
+
+ in = qcom_smem_get(pid, smem_id, &size);
+ if (IS_ERR(in))
+ return 0;
+
+ return in->version;
+}
+
+static void qcom_smp2p_start_in(struct qcom_smp2p *smp2p)
+{
+ unsigned int smem_id = smp2p->smem_items[SMP2P_INBOUND];
+ unsigned int pid = smp2p->remote_pid;
+ char buf[SMP2P_MAX_ENTRY_NAME];
+ struct smp2p_smem_item *in;
+ struct smp2p_entry *entry;
+ size_t size;
+ int i;
+
+ in = qcom_smem_get(pid, smem_id, &size);
+ if (IS_ERR(in))
+ return;
+
+ smp2p->in = in;
+
+ /* Check if version is initialized by the remote. */
+ if (in->version == 0)
+ return;
+
+ for (i = smp2p->valid_entries; i < in->valid_entries; i++) {
+ list_for_each_entry(entry, &smp2p->inbound, node) {
+ memcpy(buf, in->entries[i].name, sizeof(buf));
+ if (!strcmp(buf, entry->name)) {
+ entry->value = &in->entries[i].value;
+ entry->last_value = readl(entry->value);
+ break;
+ }
+ }
}
+ smp2p->valid_entries = i;
}
static void qcom_smp2p_notify_in(struct qcom_smp2p *smp2p)
@@ -368,12 +431,31 @@ static void smp2p_irq_print_chip(struct irq_data *irqd, struct seq_file *p)
seq_printf(p, "%8s", dev_name(entry->smp2p->dev));
}
+static int smp2p_irq_get_irqchip_state(struct irq_data *irqd, enum irqchip_irq_state which,
+ bool *state)
+{
+ struct smp2p_entry *entry = irq_data_get_irq_chip_data(irqd);
+ u32 val;
+
+ if (which != IRQCHIP_STATE_LINE_LEVEL)
+ return -EINVAL;
+
+ if (!entry->value)
+ return -ENODEV;
+
+ val = readl(entry->value);
+ *state = !!(val & BIT(irqd_to_hwirq(irqd)));
+
+ return 0;
+}
+
static struct irq_chip smp2p_irq_chip = {
.name = "smp2p",
.irq_mask = smp2p_mask_irq,
.irq_unmask = smp2p_unmask_irq,
.irq_set_type = smp2p_set_irq_type,
.irq_print_chip = smp2p_irq_print_chip,
+ .irq_get_irqchip_state = smp2p_irq_get_irqchip_state,
};
static int smp2p_irq_map(struct irq_domain *d,
@@ -464,6 +546,7 @@ static int qcom_smp2p_alloc_outbound_item(struct qcom_smp2p *smp2p)
struct smp2p_smem_item *out;
unsigned smem_id = smp2p->smem_items[SMP2P_OUTBOUND];
unsigned pid = smp2p->remote_pid;
+ u8 in_version;
int ret;
ret = qcom_smem_alloc(pid, smem_id, sizeof(*out));
@@ -485,12 +568,21 @@ static int qcom_smp2p_alloc_outbound_item(struct qcom_smp2p *smp2p)
out->valid_entries = 0;
out->features = SMP2P_ALL_FEATURES;
+ in_version = qcom_smp2p_in_version(smp2p);
+ if (in_version > MAX_VERSION) {
+ dev_err(smp2p->dev, "Unsupported smp2p version %d\n", in_version);
+ return -EINVAL;
+ }
+
/*
* Make sure the rest of the header is written before we validate the
* item by writing a valid version number.
*/
wmb();
- out->version = 1;
+ if (in_version && in_version <= 2)
+ out->version = in_version;
+ else
+ out->version = 2;
qcom_smp2p_kick(smp2p);
@@ -618,6 +710,9 @@ static int qcom_smp2p_probe(struct platform_device *pdev)
}
}
+ /* Check inbound entries in the case of early boot processor */
+ qcom_smp2p_start_in(smp2p);
+
/* Kick the outgoing edge after allocating entries */
qcom_smp2p_kick(smp2p);
diff --git a/drivers/soc/qcom/socinfo.c b/drivers/soc/qcom/socinfo.c
index 003a2304d535..8ffd903ebddb 100644
--- a/drivers/soc/qcom/socinfo.c
+++ b/drivers/soc/qcom/socinfo.c
@@ -182,6 +182,7 @@ static const char *const pmic_models[] = {
[72] = "PMR735D",
[73] = "PM8550",
[74] = "PMK8550",
+ [76] = "PM7550BA",
[78] = "PMM8650AU",
[79] = "PMM8650AU_PSAIL",
[80] = "PM7550",
@@ -473,6 +474,7 @@ static const struct soc_id soc_id[] = {
{ qcom_board_id(IPQ5000) },
{ qcom_board_id(IPQ0509) },
{ qcom_board_id(IPQ0518) },
+ { qcom_board_id(SM7450) },
{ qcom_board_id(SM6375) },
{ qcom_board_id(IPQ9514) },
{ qcom_board_id(IPQ9550) },
@@ -488,10 +490,12 @@ static const struct soc_id soc_id[] = {
{ qcom_board_id(SM8475) },
{ qcom_board_id(SM8475P) },
{ qcom_board_id(SA8255P) },
+ { qcom_board_id(SA8650P) },
{ qcom_board_id(SA8775P) },
{ qcom_board_id(QRU1000) },
{ qcom_board_id(SM8475_2) },
{ qcom_board_id(QDU1000) },
+ { qcom_board_id(SM7450P) },
{ qcom_board_id(X1E80100) },
{ qcom_board_id(SM8650) },
{ qcom_board_id(SM4450) },
@@ -522,6 +526,13 @@ static const struct soc_id soc_id[] = {
{ qcom_board_id(QCS8275) },
{ qcom_board_id(QCS9075) },
{ qcom_board_id(QCS615) },
+ { qcom_board_id(CQ7790M) },
+ { qcom_board_id(CQ7790S) },
+ { qcom_board_id(IPQ5200) },
+ { qcom_board_id(IPQ5210) },
+ { qcom_board_id(QCF2200) },
+ { qcom_board_id(QCF3200) },
+ { qcom_board_id(QCF3210) },
};
static const char *socinfo_machine(struct device *dev, unsigned int id)
diff --git a/drivers/soc/qcom/ubwc_config.c b/drivers/soc/qcom/ubwc_config.c
index 1c25aaf55e52..3fe47d8f0f63 100644
--- a/drivers/soc/qcom/ubwc_config.c
+++ b/drivers/soc/qcom/ubwc_config.c
@@ -16,6 +16,17 @@ static const struct qcom_ubwc_cfg_data no_ubwc_data = {
/* no UBWC, no HBB */
};
+static const struct qcom_ubwc_cfg_data eliza_data = {
+ .ubwc_enc_version = UBWC_5_0,
+ .ubwc_dec_version = UBWC_5_0,
+ .ubwc_swizzle = UBWC_SWIZZLE_ENABLE_LVL2 |
+ UBWC_SWIZZLE_ENABLE_LVL3,
+ .ubwc_bank_spread = true,
+ /* TODO: highest_bank_bit = 14 for LP_DDR4 */
+ .highest_bank_bit = 15,
+ .macrotile_mode = true,
+};
+
static const struct qcom_ubwc_cfg_data kaanapali_data = {
.ubwc_enc_version = UBWC_6_0,
.ubwc_dec_version = UBWC_6_0,
@@ -217,22 +228,10 @@ static const struct qcom_ubwc_cfg_data sm8750_data = {
.macrotile_mode = true,
};
-static const struct qcom_ubwc_cfg_data x1e80100_data = {
- .ubwc_enc_version = UBWC_4_0,
- .ubwc_dec_version = UBWC_4_3,
- .ubwc_swizzle = UBWC_SWIZZLE_ENABLE_LVL2 |
- UBWC_SWIZZLE_ENABLE_LVL3,
- .ubwc_bank_spread = true,
- /* TODO: highest_bank_bit = 15 for LP_DDR4 */
- .highest_bank_bit = 16,
- .macrotile_mode = true,
-};
-
static const struct qcom_ubwc_cfg_data glymur_data = {
.ubwc_enc_version = UBWC_5_0,
.ubwc_dec_version = UBWC_5_0,
- .ubwc_swizzle = UBWC_SWIZZLE_ENABLE_LVL2 |
- UBWC_SWIZZLE_ENABLE_LVL3,
+ .ubwc_swizzle = 0,
.ubwc_bank_spread = true,
/* TODO: highest_bank_bit = 15 for LP_DDR4 */
.highest_bank_bit = 16,
@@ -244,8 +243,10 @@ static const struct of_device_id qcom_ubwc_configs[] __maybe_unused = {
{ .compatible = "qcom,apq8026", .data = &no_ubwc_data },
{ .compatible = "qcom,apq8074", .data = &no_ubwc_data },
{ .compatible = "qcom,apq8096", .data = &msm8998_data },
+ { .compatible = "qcom,eliza", .data = &eliza_data, },
{ .compatible = "qcom,kaanapali", .data = &kaanapali_data, },
{ .compatible = "qcom,glymur", .data = &glymur_data},
+ { .compatible = "qcom,mahua", .data = &glymur_data },
{ .compatible = "qcom,msm8226", .data = &no_ubwc_data },
{ .compatible = "qcom,msm8916", .data = &no_ubwc_data },
{ .compatible = "qcom,msm8917", .data = &no_ubwc_data },
@@ -294,8 +295,8 @@ static const struct of_device_id qcom_ubwc_configs[] __maybe_unused = {
{ .compatible = "qcom,sm8550", .data = &sm8550_data, },
{ .compatible = "qcom,sm8650", .data = &sm8550_data, },
{ .compatible = "qcom,sm8750", .data = &sm8750_data, },
- { .compatible = "qcom,x1e80100", .data = &x1e80100_data, },
- { .compatible = "qcom,x1p42100", .data = &x1e80100_data, },
+ { .compatible = "qcom,x1e80100", .data = &sm8550_data, },
+ { .compatible = "qcom,x1p42100", .data = &sm8550_data, },
{ }
};
diff --git a/drivers/soc/qcom/wcnss_ctrl.c b/drivers/soc/qcom/wcnss_ctrl.c
index 62b424e90d90..ffb31a049d4a 100644
--- a/drivers/soc/qcom/wcnss_ctrl.c
+++ b/drivers/soc/qcom/wcnss_ctrl.c
@@ -94,7 +94,7 @@ struct wcnss_download_nv_req {
u16 seq;
u16 last;
u32 frag_size;
- u8 fragment[];
+ u8 fragment[] __counted_by(frag_size);
} __packed;
/**
@@ -201,16 +201,12 @@ static int wcnss_download_nv(struct wcnss_ctrl *wcnss, bool *expect_cbc)
{
const struct firmware *fw;
struct device *dev = wcnss->dev;
+ struct wcnss_download_nv_req *req;
const char *nvbin = NVBIN_FILE;
const void *data;
ssize_t left;
int ret;
- struct wcnss_download_nv_req *req __free(kfree) = kzalloc(sizeof(*req) + NV_FRAGMENT_SIZE,
- GFP_KERNEL);
- if (!req)
- return -ENOMEM;
-
ret = of_property_read_string(dev->of_node, "firmware-name", &nvbin);
if (ret < 0 && ret != -EINVAL)
return ret;
@@ -224,11 +220,15 @@ static int wcnss_download_nv(struct wcnss_ctrl *wcnss, bool *expect_cbc)
data = fw->data;
left = fw->size;
+ req = kzalloc_flex(*req, fragment, NV_FRAGMENT_SIZE);
+ if (!req)
+ return -ENOMEM;
+
+ req->frag_size = NV_FRAGMENT_SIZE;
req->hdr.type = WCNSS_DOWNLOAD_NV_REQ;
- req->hdr.len = sizeof(*req) + NV_FRAGMENT_SIZE;
+ req->hdr.len = struct_size(req, fragment, NV_FRAGMENT_SIZE);
req->last = 0;
- req->frag_size = NV_FRAGMENT_SIZE;
req->seq = 0;
do {
@@ -264,6 +264,7 @@ static int wcnss_download_nv(struct wcnss_ctrl *wcnss, bool *expect_cbc)
release_fw:
release_firmware(fw);
+ kfree(req);
return ret;
}
diff --git a/drivers/soc/renesas/Kconfig b/drivers/soc/renesas/Kconfig
index 1e50dc7c31cd..26bed0fdceb0 100644
--- a/drivers/soc/renesas/Kconfig
+++ b/drivers/soc/renesas/Kconfig
@@ -390,6 +390,14 @@ config ARCH_R9A08G045
help
This enables support for the Renesas RZ/G3S SoC variants.
+config ARCH_R9A08G046
+ bool "ARM64 Platform support for R9A08G046 (RZ/G3L)"
+ default y if ARCH_RENESAS
+ select ARCH_RZG2L
+ select SYSC_R9A08G046
+ help
+ This enables support for the Renesas RZ/G3L SoC variants.
+
config ARCH_R9A09G011
bool "ARM64 Platform support for R9A09G011 (RZ/V2M)"
default y if ARCH_RENESAS
@@ -474,6 +482,10 @@ config SYSC_R9A08G045
bool "Renesas System controller support for R9A08G045 (RZ/G3S)" if COMPILE_TEST
select SYSC_RZ
+config SYSC_R9A08G046
+ bool "Renesas System controller support for R9A08G046 (RZ/G3L)" if COMPILE_TEST
+ select SYSC_RZ
+
config SYS_R9A09G047
bool "Renesas System controller support for R9A09G047 (RZ/G3E)" if COMPILE_TEST
select SYSC_RZ
diff --git a/drivers/soc/renesas/Makefile b/drivers/soc/renesas/Makefile
index 33d44d964d61..655dbcb08747 100644
--- a/drivers/soc/renesas/Makefile
+++ b/drivers/soc/renesas/Makefile
@@ -7,6 +7,7 @@ ifdef CONFIG_SMP
obj-$(CONFIG_ARCH_R9A06G032) += r9a06g032-smp.o
endif
obj-$(CONFIG_SYSC_R9A08G045) += r9a08g045-sysc.o
+obj-$(CONFIG_SYSC_R9A08G046) += r9a08g046-sysc.o
obj-$(CONFIG_SYS_R9A09G047) += r9a09g047-sys.o
obj-$(CONFIG_SYS_R9A09G056) += r9a09g056-sys.o
obj-$(CONFIG_SYS_R9A09G057) += r9a09g057-sys.o
diff --git a/drivers/soc/renesas/r9a08g046-sysc.c b/drivers/soc/renesas/r9a08g046-sysc.c
new file mode 100644
index 000000000000..fd98df196d0a
--- /dev/null
+++ b/drivers/soc/renesas/r9a08g046-sysc.c
@@ -0,0 +1,91 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * RZ/G3L System controller (SYSC) driver
+ *
+ * Copyright (C) 2026 Renesas Electronics Corp.
+ */
+
+#include <linux/bits.h>
+#include <linux/device.h>
+#include <linux/init.h>
+
+#include "rz-sysc.h"
+
+#define SYS_XSPI_MAP_STAADD_CS0 0x348
+#define SYS_XSPI_MAP_ENDADD_CS0 0x34c
+#define SYS_XSPI_MAP_STAADD_CS1 0x350
+#define SYS_XSPI_MAP_ENDADD_CS1 0x354
+#define SYS_GETH0_CFG 0x380
+#define SYS_GETH1_CFG 0x390
+#define SYS_PCIE_CFG 0x3a0
+#define SYS_PCIE_MON 0x3a4
+#define SYS_PCIE_PHY 0x3b4
+#define SYS_I2C0_CFG 0x400
+#define SYS_I2C1_CFG 0x410
+#define SYS_I2C2_CFG 0x420
+#define SYS_I2C3_CFG 0x430
+#define SYS_I3C_CFG 0x440
+#define SYS_PWRRDY_N 0xd70
+#define SYS_IPCONT_SEL_CLONECH 0xe2c
+
+static bool rzg3l_regmap_readable_reg(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case SYS_XSPI_MAP_STAADD_CS0:
+ case SYS_XSPI_MAP_ENDADD_CS0:
+ case SYS_XSPI_MAP_STAADD_CS1:
+ case SYS_XSPI_MAP_ENDADD_CS1:
+ case SYS_GETH0_CFG:
+ case SYS_GETH1_CFG:
+ case SYS_PCIE_CFG:
+ case SYS_PCIE_MON:
+ case SYS_PCIE_PHY:
+ case SYS_I2C0_CFG:
+ case SYS_I2C1_CFG:
+ case SYS_I2C2_CFG:
+ case SYS_I2C3_CFG:
+ case SYS_I3C_CFG:
+ case SYS_PWRRDY_N:
+ case SYS_IPCONT_SEL_CLONECH:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool rzg3l_regmap_writeable_reg(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case SYS_XSPI_MAP_STAADD_CS0:
+ case SYS_XSPI_MAP_ENDADD_CS0:
+ case SYS_XSPI_MAP_STAADD_CS1:
+ case SYS_XSPI_MAP_ENDADD_CS1:
+ case SYS_PCIE_CFG:
+ case SYS_PCIE_PHY:
+ case SYS_I2C0_CFG:
+ case SYS_I2C1_CFG:
+ case SYS_I2C2_CFG:
+ case SYS_I2C3_CFG:
+ case SYS_I3C_CFG:
+ case SYS_PWRRDY_N:
+ case SYS_IPCONT_SEL_CLONECH:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static const struct rz_sysc_soc_id_init_data rzg3l_sysc_soc_id_init_data __initconst = {
+ .family = "RZ/G3L",
+ .id = 0x87d9447,
+ .devid_offset = 0xa04,
+ .revision_mask = GENMASK(31, 28),
+ .specific_id_mask = GENMASK(27, 0),
+};
+
+const struct rz_sysc_init_data rzg3l_sysc_init_data __initconst = {
+ .soc_id_init_data = &rzg3l_sysc_soc_id_init_data,
+ .readable_reg = rzg3l_regmap_readable_reg,
+ .writeable_reg = rzg3l_regmap_writeable_reg,
+ .max_register = 0xe2c,
+};
diff --git a/drivers/soc/renesas/r9a09g047-sys.c b/drivers/soc/renesas/r9a09g047-sys.c
index e413b0eff9bf..ea3ca10fcc33 100644
--- a/drivers/soc/renesas/r9a09g047-sys.c
+++ b/drivers/soc/renesas/r9a09g047-sys.c
@@ -139,7 +139,7 @@ static bool rzg3e_regmap_writeable_reg(struct device *dev, unsigned int reg)
}
}
-const struct rz_sysc_init_data rzg3e_sys_init_data = {
+const struct rz_sysc_init_data rzg3e_sys_init_data __initconst = {
.soc_id_init_data = &rzg3e_sys_soc_id_init_data,
.readable_reg = rzg3e_regmap_readable_reg,
.writeable_reg = rzg3e_regmap_writeable_reg,
diff --git a/drivers/soc/renesas/r9a09g056-sys.c b/drivers/soc/renesas/r9a09g056-sys.c
index 42f5eff291fd..2a8ebc209961 100644
--- a/drivers/soc/renesas/r9a09g056-sys.c
+++ b/drivers/soc/renesas/r9a09g056-sys.c
@@ -136,7 +136,7 @@ static bool rzv2n_regmap_writeable_reg(struct device *dev, unsigned int reg)
}
}
-const struct rz_sysc_init_data rzv2n_sys_init_data = {
+const struct rz_sysc_init_data rzv2n_sys_init_data __initconst = {
.soc_id_init_data = &rzv2n_sys_soc_id_init_data,
.readable_reg = rzv2n_regmap_readable_reg,
.writeable_reg = rzv2n_regmap_writeable_reg,
diff --git a/drivers/soc/renesas/r9a09g057-sys.c b/drivers/soc/renesas/r9a09g057-sys.c
index 827c718ac7c5..f3e054206acb 100644
--- a/drivers/soc/renesas/r9a09g057-sys.c
+++ b/drivers/soc/renesas/r9a09g057-sys.c
@@ -161,7 +161,7 @@ static bool rzv2h_regmap_writeable_reg(struct device *dev, unsigned int reg)
}
}
-const struct rz_sysc_init_data rzv2h_sys_init_data = {
+const struct rz_sysc_init_data rzv2h_sys_init_data __initconst = {
.soc_id_init_data = &rzv2h_sys_soc_id_init_data,
.readable_reg = rzv2h_regmap_readable_reg,
.writeable_reg = rzv2h_regmap_writeable_reg,
diff --git a/drivers/soc/renesas/rz-sysc.c b/drivers/soc/renesas/rz-sysc.c
index 7471dc8736e6..161e8c38eea6 100644
--- a/drivers/soc/renesas/rz-sysc.c
+++ b/drivers/soc/renesas/rz-sysc.c
@@ -88,6 +88,9 @@ static const struct of_device_id rz_sysc_match[] = {
#ifdef CONFIG_SYSC_R9A08G045
{ .compatible = "renesas,r9a08g045-sysc", .data = &rzg3s_sysc_init_data },
#endif
+#ifdef CONFIG_SYSC_R9A08G046
+ { .compatible = "renesas,r9a08g046-sysc", .data = &rzg3l_sysc_init_data },
+#endif
#ifdef CONFIG_SYS_R9A09G047
{ .compatible = "renesas,r9a09g047-sys", .data = &rzg3e_sys_init_data },
#endif
diff --git a/drivers/soc/renesas/rz-sysc.h b/drivers/soc/renesas/rz-sysc.h
index 88929bf21cb1..921ee0d26c47 100644
--- a/drivers/soc/renesas/rz-sysc.h
+++ b/drivers/soc/renesas/rz-sysc.h
@@ -46,6 +46,7 @@ struct rz_sysc_init_data {
};
extern const struct rz_sysc_init_data rzg3e_sys_init_data;
+extern const struct rz_sysc_init_data rzg3l_sysc_init_data;
extern const struct rz_sysc_init_data rzg3s_sysc_init_data;
extern const struct rz_sysc_init_data rzv2h_sys_init_data;
extern const struct rz_sysc_init_data rzv2n_sys_init_data;
diff --git a/drivers/soc/tegra/Kconfig b/drivers/soc/tegra/Kconfig
index c0fc54c3cd35..073346c1542b 100644
--- a/drivers/soc/tegra/Kconfig
+++ b/drivers/soc/tegra/Kconfig
@@ -6,6 +6,7 @@ if ARM
config ARCH_TEGRA_2x_SOC
bool "Enable support for Tegra20 family"
+ default ARCH_TEGRA
select ARCH_NEEDS_CPU_IDLE_COUPLED if SMP
select ARM_ERRATA_720789
select ARM_ERRATA_754327 if SMP
@@ -23,6 +24,7 @@ config ARCH_TEGRA_2x_SOC
config ARCH_TEGRA_3x_SOC
bool "Enable support for Tegra30 family"
+ default ARCH_TEGRA
select ARM_ERRATA_754322
select ARM_ERRATA_764369 if SMP
select PINCTRL_TEGRA30
@@ -37,6 +39,7 @@ config ARCH_TEGRA_3x_SOC
config ARCH_TEGRA_114_SOC
bool "Enable support for Tegra114 family"
+ default ARCH_TEGRA
select ARM_ERRATA_798181 if SMP
select HAVE_ARM_ARCH_TIMER
select PINCTRL_TEGRA114
@@ -49,6 +52,7 @@ config ARCH_TEGRA_114_SOC
config ARCH_TEGRA_124_SOC
bool "Enable support for Tegra124 family"
+ default ARCH_TEGRA
select HAVE_ARM_ARCH_TIMER
select PINCTRL_TEGRA124
select SOC_TEGRA_FLOWCTRL
@@ -65,6 +69,7 @@ if ARM64
config ARCH_TEGRA_132_SOC
bool "NVIDIA Tegra132 SoC"
+ default ARCH_TEGRA
select PINCTRL_TEGRA124
select SOC_TEGRA_FLOWCTRL
select SOC_TEGRA_PMC
@@ -76,6 +81,7 @@ config ARCH_TEGRA_132_SOC
config ARCH_TEGRA_210_SOC
bool "NVIDIA Tegra210 SoC"
+ default ARCH_TEGRA
select PINCTRL_TEGRA210
select SOC_TEGRA_FLOWCTRL
select SOC_TEGRA_PMC
@@ -95,6 +101,7 @@ config ARCH_TEGRA_210_SOC
config ARCH_TEGRA_186_SOC
bool "NVIDIA Tegra186 SoC"
+ default ARCH_TEGRA
depends on !CPU_BIG_ENDIAN
select PINCTRL_TEGRA186
select MAILBOX
@@ -109,6 +116,7 @@ config ARCH_TEGRA_186_SOC
config ARCH_TEGRA_194_SOC
bool "NVIDIA Tegra194 SoC"
+ default ARCH_TEGRA
depends on !CPU_BIG_ENDIAN
select MAILBOX
select PINCTRL_TEGRA194
@@ -118,6 +126,7 @@ config ARCH_TEGRA_194_SOC
config ARCH_TEGRA_234_SOC
bool "NVIDIA Tegra234 SoC"
+ default ARCH_TEGRA
depends on !CPU_BIG_ENDIAN
select MAILBOX
select PINCTRL_TEGRA234
@@ -125,13 +134,24 @@ config ARCH_TEGRA_234_SOC
help
Enable support for the NVIDIA Tegra234 SoC.
+config ARCH_TEGRA_238_SOC
+ bool "NVIDIA Tegra238 SoC"
+ default ARCH_TEGRA
+ depends on !CPU_BIG_ENDIAN
+ select MAILBOX
+ select SOC_TEGRA_PMC
+ help
+ Enable support for the NVIDIA Tegra238 SoC.
+
config ARCH_TEGRA_241_SOC
bool "NVIDIA Tegra241 SoC"
+ default ARCH_TEGRA
help
Enable support for the NVIDIA Tegra241 SoC.
config ARCH_TEGRA_264_SOC
bool "NVIDIA Tegra264 SoC"
+ default ARCH_TEGRA
depends on !CPU_BIG_ENDIAN
select MAILBOX
select SOC_TEGRA_PMC
diff --git a/drivers/soc/tegra/cbb/tegra234-cbb.c b/drivers/soc/tegra/cbb/tegra234-cbb.c
index a9adbcecd47c..fb26f085f691 100644
--- a/drivers/soc/tegra/cbb/tegra234-cbb.c
+++ b/drivers/soc/tegra/cbb/tegra234-cbb.c
@@ -89,6 +89,15 @@ enum tegra234_cbb_fabric_ids {
T234_MAX_FABRIC_ID,
};
+enum tegra238_cbb_fabric_ids {
+ T238_CBB_FABRIC_ID = 0,
+ T238_AON_FABRIC_ID = 4,
+ T238_PSC_FABRIC_ID = 5,
+ T238_BPMP_FABRIC_ID = 6,
+ T238_APE_FABRIC_ID = 7,
+ T238_MAX_FABRIC_ID,
+};
+
enum tegra264_cbb_fabric_ids {
T264_SYSTEM_CBB_FABRIC_ID,
T264_TOP_0_CBB_FABRIC_ID,
@@ -313,12 +322,37 @@ static void tegra234_cbb_lookup_apbslv(struct seq_file *file, const char *target
}
}
+static struct tegra234_cbb *tegra234_cbb_get_fabric(u8 fab_id)
+{
+ struct tegra_cbb *entry;
+
+ list_for_each_entry(entry, &cbb_list, node) {
+ struct tegra234_cbb *priv = to_tegra234_cbb(entry);
+
+ if (priv->fabric->fab_id == fab_id)
+ return priv;
+ }
+
+ return NULL;
+}
+
static void tegra234_sw_lookup_target_timeout(struct seq_file *file, struct tegra234_cbb *cbb,
u8 target_id, u8 fab_id)
{
const struct tegra234_target_lookup *map = cbb->fabric->fab_list[fab_id].target_map;
+ struct tegra234_cbb *target_cbb = NULL;
void __iomem *addr;
+ if (fab_id == cbb->fabric->fab_id)
+ target_cbb = cbb;
+ else
+ target_cbb = tegra234_cbb_get_fabric(fab_id);
+
+ if (!target_cbb) {
+ dev_err(cbb->base.dev, "could not find fabric for fab_id:%d\n", fab_id);
+ return;
+ }
+
if (target_id >= cbb->fabric->fab_list[fab_id].max_targets) {
tegra_cbb_print_err(file, "\t Invalid target_id:%d\n", target_id);
return;
@@ -341,7 +375,7 @@ static void tegra234_sw_lookup_target_timeout(struct seq_file *file, struct tegr
* e) Goto step-a till all bits are set.
*/
- addr = cbb->regs + map[target_id].offset;
+ addr = target_cbb->regs + map[target_id].offset;
if (strstr(map[target_id].name, "AXI2APB")) {
addr += APB_BLOCK_TMO_STATUS_0;
@@ -881,7 +915,7 @@ static const struct tegra234_fabric_lookup tegra234_cbb_fab_list[] = {
ARRAY_SIZE(tegra234_common_target_map) },
[T234_AON_FABRIC_ID] = { "aon-fabric", true,
tegra234_aon_target_map,
- ARRAY_SIZE(tegra234_bpmp_target_map) },
+ ARRAY_SIZE(tegra234_aon_target_map) },
[T234_PSC_FABRIC_ID] = { "psc-fabric" },
[T234_BPMP_FABRIC_ID] = { "bpmp-fabric", true,
tegra234_bpmp_target_map,
@@ -974,6 +1008,127 @@ static const struct tegra234_cbb_fabric tegra234_sce_fabric = {
.firewall_wr_ctl = 0x288,
};
+static const struct tegra234_target_lookup tegra238_ape_target_map[] = {
+ { "AXI2APB", 0x00000 },
+ { "AGIC", 0x15000 },
+ { "AMC", 0x16000 },
+ { "AST0", 0x17000 },
+ { "AST1", 0x18000 },
+ { "AST2", 0x19000 },
+ { "CBB", 0x1A000 },
+};
+
+static const struct tegra234_target_lookup tegra238_cbb_target_map[] = {
+ { "AON", 0x40000 },
+ { "APE", 0x50000 },
+ { "BPMP", 0x41000 },
+ { "HOST1X", 0x43000 },
+ { "STM", 0x44000 },
+ { "CBB_CENTRAL", 0x00000 },
+ { "PCIE_C0", 0x51000 },
+ { "PCIE_C1", 0x47000 },
+ { "PCIE_C2", 0x48000 },
+ { "PCIE_C3", 0x49000 },
+ { "GPU", 0x4C000 },
+ { "SMMU0", 0x4D000 },
+ { "SMMU1", 0x4E000 },
+ { "SMMU2", 0x4F000 },
+ { "PSC", 0x52000 },
+ { "AXI2APB_1", 0x70000 },
+ { "AXI2APB_12", 0x73000 },
+ { "AXI2APB_13", 0x74000 },
+ { "AXI2APB_15", 0x76000 },
+ { "AXI2APB_16", 0x77000 },
+ { "AXI2APB_18", 0x79000 },
+ { "AXI2APB_19", 0x7A000 },
+ { "AXI2APB_2", 0x7B000 },
+ { "AXI2APB_23", 0x7F000 },
+ { "AXI2APB_25", 0x80000 },
+ { "AXI2APB_26", 0x81000 },
+ { "AXI2APB_27", 0x82000 },
+ { "AXI2APB_28", 0x83000 },
+ { "AXI2APB_32", 0x87000 },
+ { "AXI2APB_33", 0x88000 },
+ { "AXI2APB_4", 0x8B000 },
+ { "AXI2APB_5", 0x8C000 },
+ { "AXI2APB_6", 0x93000 },
+ { "AXI2APB_9", 0x90000 },
+ { "AXI2APB_3", 0x91000 },
+};
+
+static const struct tegra234_fabric_lookup tegra238_cbb_fab_list[] = {
+ [T238_CBB_FABRIC_ID] = { "cbb-fabric", true,
+ tegra238_cbb_target_map,
+ ARRAY_SIZE(tegra238_cbb_target_map) },
+ [T238_AON_FABRIC_ID] = { "aon-fabric", true,
+ tegra234_aon_target_map,
+ ARRAY_SIZE(tegra234_aon_target_map) },
+ [T238_PSC_FABRIC_ID] = { "psc-fabric" },
+ [T238_BPMP_FABRIC_ID] = { "bpmp-fabric", true,
+ tegra234_bpmp_target_map,
+ ARRAY_SIZE(tegra234_bpmp_target_map) },
+ [T238_APE_FABRIC_ID] = { "ape-fabric", true,
+ tegra238_ape_target_map,
+ ARRAY_SIZE(tegra238_ape_target_map) },
+};
+
+static const struct tegra234_cbb_fabric tegra238_aon_fabric = {
+ .fab_id = T238_AON_FABRIC_ID,
+ .fab_list = tegra238_cbb_fab_list,
+ .initiator_id = tegra234_initiator_id,
+ .errors = tegra234_cbb_errors,
+ .max_errors = ARRAY_SIZE(tegra234_cbb_errors),
+ .err_intr_enbl = 0x7,
+ .err_status_clr = 0x3f,
+ .notifier_offset = 0x17000,
+ .firewall_base = 0x30000,
+ .firewall_ctl = 0x8f0,
+ .firewall_wr_ctl = 0x8e8,
+};
+
+static const struct tegra234_cbb_fabric tegra238_ape_fabric = {
+ .fab_id = T238_APE_FABRIC_ID,
+ .fab_list = tegra238_cbb_fab_list,
+ .initiator_id = tegra234_initiator_id,
+ .errors = tegra234_cbb_errors,
+ .max_errors = ARRAY_SIZE(tegra234_cbb_errors),
+ .err_intr_enbl = 0xf,
+ .err_status_clr = 0x3f,
+ .notifier_offset = 0x1E000,
+ .firewall_base = 0x30000,
+ .firewall_ctl = 0xad0,
+ .firewall_wr_ctl = 0xac8,
+};
+
+static const struct tegra234_cbb_fabric tegra238_bpmp_fabric = {
+ .fab_id = T238_BPMP_FABRIC_ID,
+ .fab_list = tegra238_cbb_fab_list,
+ .initiator_id = tegra234_initiator_id,
+ .errors = tegra234_cbb_errors,
+ .max_errors = ARRAY_SIZE(tegra234_cbb_errors),
+ .err_intr_enbl = 0xf,
+ .err_status_clr = 0x3f,
+ .notifier_offset = 0x19000,
+ .firewall_base = 0x30000,
+ .firewall_ctl = 0x8f0,
+ .firewall_wr_ctl = 0x8e8,
+};
+
+static const struct tegra234_cbb_fabric tegra238_cbb_fabric = {
+ .fab_id = T238_CBB_FABRIC_ID,
+ .fab_list = tegra238_cbb_fab_list,
+ .initiator_id = tegra234_initiator_id,
+ .errors = tegra234_cbb_errors,
+ .max_errors = ARRAY_SIZE(tegra234_cbb_errors),
+ .err_intr_enbl = 0x3f,
+ .err_status_clr = 0x3f,
+ .notifier_offset = 0x60000,
+ .off_mask_erd = 0x3d004,
+ .firewall_base = 0x10000,
+ .firewall_ctl = 0x2230,
+ .firewall_wr_ctl = 0x2228,
+};
+
static const char * const tegra241_initiator_id[] = {
[0x0] = "TZ",
[0x1] = "CCPLEX",
@@ -1160,7 +1315,7 @@ static const struct tegra234_fabric_lookup tegra241_cbb_fab_list[] = {
[T234_CBB_FABRIC_ID] = { "cbb-fabric", true,
tegra241_cbb_target_map, ARRAY_SIZE(tegra241_cbb_target_map) },
[T234_BPMP_FABRIC_ID] = { "bpmp-fabric", true,
- tegra241_bpmp_target_map, ARRAY_SIZE(tegra241_cbb_target_map) },
+ tegra241_bpmp_target_map, ARRAY_SIZE(tegra241_bpmp_target_map) },
};
static const struct tegra234_cbb_fabric tegra241_cbb_fabric = {
.fab_id = T234_CBB_FABRIC_ID,
@@ -1480,6 +1635,10 @@ static const struct of_device_id tegra234_cbb_dt_ids[] = {
{ .compatible = "nvidia,tegra234-dce-fabric", .data = &tegra234_dce_fabric },
{ .compatible = "nvidia,tegra234-rce-fabric", .data = &tegra234_rce_fabric },
{ .compatible = "nvidia,tegra234-sce-fabric", .data = &tegra234_sce_fabric },
+ { .compatible = "nvidia,tegra238-aon-fabric", .data = &tegra238_aon_fabric },
+ { .compatible = "nvidia,tegra238-ape-fabric", .data = &tegra238_ape_fabric },
+ { .compatible = "nvidia,tegra238-bpmp-fabric", .data = &tegra238_bpmp_fabric },
+ { .compatible = "nvidia,tegra238-cbb-fabric", .data = &tegra238_cbb_fabric },
{ .compatible = "nvidia,tegra264-sys-cbb-fabric", .data = &tegra264_sys_cbb_fabric },
{ .compatible = "nvidia,tegra264-top0-cbb-fabric", .data = &tegra264_top0_cbb_fabric },
{ .compatible = "nvidia,tegra264-uphy0-cbb-fabric", .data = &tegra264_uphy0_cbb_fabric },
@@ -1586,6 +1745,10 @@ static int __maybe_unused tegra234_cbb_resume_noirq(struct device *dev)
{
struct tegra234_cbb *cbb = dev_get_drvdata(dev);
+ /* set ERD bit to mask SError and generate interrupt to report error */
+ if (cbb->fabric->off_mask_erd)
+ tegra234_cbb_mask_serror(cbb);
+
tegra234_cbb_error_enable(&cbb->base);
dev_dbg(dev, "%s resumed\n", cbb->fabric->fab_list[cbb->fabric->fab_id].name);
diff --git a/drivers/soc/tegra/common.c b/drivers/soc/tegra/common.c
index d82b7670abb7..0864eb0185b4 100644
--- a/drivers/soc/tegra/common.c
+++ b/drivers/soc/tegra/common.c
@@ -118,7 +118,8 @@ int devm_tegra_core_dev_init_opp_table(struct device *dev,
hw_version = BIT(tegra_sku_info.soc_process_id);
config.supported_hw = &hw_version;
config.supported_hw_count = 1;
- } else if (of_machine_is_compatible("nvidia,tegra30")) {
+ } else if (of_machine_is_compatible("nvidia,tegra30") ||
+ of_machine_is_compatible("nvidia,tegra114")) {
hw_version = BIT(tegra_sku_info.soc_speedo_id);
config.supported_hw = &hw_version;
config.supported_hw_count = 1;
@@ -131,7 +132,7 @@ int devm_tegra_core_dev_init_opp_table(struct device *dev,
}
/*
- * Tegra114+ doesn't support OPP yet, return early for non tegra20/30
+ * Tegra124+ doesn't support OPP yet, return early for pre-Tegra124
* case.
*/
if (!config.supported_hw)
diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c
index a1a2966512d1..2ee6539d796a 100644
--- a/drivers/soc/tegra/pmc.c
+++ b/drivers/soc/tegra/pmc.c
@@ -60,6 +60,7 @@
#include <dt-bindings/gpio/tegra186-gpio.h>
#include <dt-bindings/gpio/tegra194-gpio.h>
#include <dt-bindings/gpio/tegra234-gpio.h>
+#include <dt-bindings/gpio/nvidia,tegra264-gpio.h>
#include <dt-bindings/soc/tegra-pmc.h>
#define PMC_CNTRL 0x0
@@ -180,19 +181,18 @@
#define WAKE_AOWAKE_CNTRL(x) (0x000 + ((x) << 2))
#define WAKE_AOWAKE_CNTRL_LEVEL (1 << 3)
#define WAKE_AOWAKE_CNTRL_SR_CAPTURE_EN (1 << 1)
-#define WAKE_AOWAKE_MASK_W(x) (0x180 + ((x) << 2))
-#define WAKE_AOWAKE_MASK_R(x) (0x300 + ((x) << 2))
-#define WAKE_AOWAKE_STATUS_W(x) (0x30c + ((x) << 2))
-#define WAKE_AOWAKE_STATUS_R(x) (0x48c + ((x) << 2))
-#define WAKE_AOWAKE_TIER0_ROUTING(x) (0x4b4 + ((x) << 2))
-#define WAKE_AOWAKE_TIER1_ROUTING(x) (0x4c0 + ((x) << 2))
-#define WAKE_AOWAKE_TIER2_ROUTING(x) (0x4cc + ((x) << 2))
-#define WAKE_AOWAKE_SW_STATUS_W_0 0x49c
-#define WAKE_AOWAKE_SW_STATUS(x) (0x4a0 + ((x) << 2))
-#define WAKE_LATCH_SW 0x498
-
-#define WAKE_AOWAKE_CTRL 0x4f4
-#define WAKE_AOWAKE_CTRL_INTR_POLARITY BIT(0)
+#define WAKE_AOWAKE_MASK_W(_pmc, x) \
+ ((_pmc)->soc->regs->aowake_mask_w + ((x) << 2))
+#define WAKE_AOWAKE_STATUS_W(_pmc, x) \
+ ((_pmc)->soc->regs->aowake_status_w + ((x) << 2))
+#define WAKE_AOWAKE_STATUS_R(_pmc, x) \
+ ((_pmc)->soc->regs->aowake_status_r + ((x) << 2))
+#define WAKE_AOWAKE_TIER2_ROUTING(_pmc, x) \
+ ((_pmc)->soc->regs->aowake_tier2_routing + ((x) << 2))
+#define WAKE_AOWAKE_SW_STATUS(_pmc, x) \
+ ((_pmc)->soc->regs->aowake_sw_status + ((x) << 2))
+
+#define WAKE_AOWAKE_CTRL_INTR_POLARITY BIT(0)
#define SW_WAKE_ID 83 /* wake83 */
@@ -201,6 +201,9 @@
#define TEGRA_SMC_PMC_READ 0xaa
#define TEGRA_SMC_PMC_WRITE 0xbb
+/* Tegra264 and later */
+#define PMC_IMPL_SDMMC1_HV_PADCTL_0 0x41004
+
struct pmc_clk {
struct clk_hw hw;
struct tegra_pmc *pmc;
@@ -294,10 +297,16 @@ struct tegra_io_pad_soc {
unsigned int dpd;
unsigned int request;
unsigned int status;
- unsigned int voltage;
const char *name;
};
+struct tegra_io_pad_vctrl {
+ enum tegra_io_pad id;
+ unsigned int offset;
+ unsigned int ena_3v3;
+ unsigned int ena_1v8;
+};
+
struct tegra_pmc_regs {
unsigned int scratch0;
unsigned int rst_status;
@@ -305,6 +314,14 @@ struct tegra_pmc_regs {
unsigned int rst_source_mask;
unsigned int rst_level_shift;
unsigned int rst_level_mask;
+ unsigned int aowake_mask_w;
+ unsigned int aowake_status_w;
+ unsigned int aowake_status_r;
+ unsigned int aowake_tier2_routing;
+ unsigned int aowake_sw_status_w;
+ unsigned int aowake_sw_status;
+ unsigned int aowake_latch_sw;
+ unsigned int aowake_ctrl;
};
struct tegra_wake_event {
@@ -359,11 +376,13 @@ struct tegra_pmc_soc {
bool has_tsense_reset;
bool has_gpu_clamps;
bool needs_mbist_war;
- bool has_impl_33v_pwr;
+ bool has_io_pad_wren;
bool maybe_tz_only;
const struct tegra_io_pad_soc *io_pads;
unsigned int num_io_pads;
+ const struct tegra_io_pad_vctrl *io_pad_vctrls;
+ unsigned int num_io_pad_vctrls;
const struct pinctrl_pin_desc *pin_descs;
unsigned int num_pin_descs;
@@ -437,7 +456,10 @@ struct tegra_pmc_soc {
* @wake_sw_status_map: Bitmap to hold raw status of wakes without mask
* @wake_cntrl_level_map: Bitmap to hold wake levels to be programmed in
* cntrl register associated with each wake during system suspend.
+ * @reboot_notifier: PMC reboot notifier handler
* @syscore: syscore suspend/resume callbacks
+ * @wake_work: IRQ work handler for processing wake-up events.
+ * @wake_status: Status of wake-up events.
*/
struct tegra_pmc {
struct device *dev;
@@ -1004,7 +1026,7 @@ static struct tegra_pmc *tegra_pmc_get(struct device *dev)
}
/**
- * tegra_pmc_get() - find the PMC for a given device
+ * devm_tegra_pmc_get() - find the PMC for a given device
* @dev: device for which to find the PMC
*
* Returns a pointer to the PMC on success or an ERR_PTR()-encoded error code
@@ -1688,6 +1710,18 @@ tegra_io_pad_find(struct tegra_pmc *pmc, enum tegra_io_pad id)
return NULL;
}
+static const struct tegra_io_pad_vctrl *
+tegra_io_pad_vctrl_find(struct tegra_pmc *pmc, enum tegra_io_pad id)
+{
+ unsigned int i;
+
+ for (i = 0; i < pmc->soc->num_io_pad_vctrls; i++)
+ if (pmc->soc->io_pad_vctrls[i].id == id)
+ return &pmc->soc->io_pad_vctrls[i];
+
+ return NULL;
+}
+
static int tegra_io_pad_prepare(struct tegra_pmc *pmc,
const struct tegra_io_pad_soc *pad,
unsigned long *request,
@@ -1746,7 +1780,7 @@ static void tegra_io_pad_unprepare(struct tegra_pmc *pmc)
}
/**
- * tegra_io_pad_power_enable() - enable power to I/O pad
+ * tegra_pmc_io_pad_power_enable() - enable power to I/O pad
* @pmc: power management controller
* @id: Tegra I/O pad ID for which to enable power
*
@@ -1883,44 +1917,38 @@ static int tegra_io_pad_is_powered(struct tegra_pmc *pmc, enum tegra_io_pad id)
static int tegra_io_pad_set_voltage(struct tegra_pmc *pmc, enum tegra_io_pad id,
int voltage)
{
- const struct tegra_io_pad_soc *pad;
+ const struct tegra_io_pad_vctrl *pad;
u32 value;
- pad = tegra_io_pad_find(pmc, id);
+ pad = tegra_io_pad_vctrl_find(pmc, id);
if (!pad)
return -ENOENT;
- if (pad->voltage == UINT_MAX)
- return -ENOTSUPP;
-
mutex_lock(&pmc->powergates_lock);
- if (pmc->soc->has_impl_33v_pwr) {
- value = tegra_pmc_readl(pmc, PMC_IMPL_E_33V_PWR);
-
- if (voltage == TEGRA_IO_PAD_VOLTAGE_1V8)
- value &= ~BIT(pad->voltage);
- else
- value |= BIT(pad->voltage);
-
- tegra_pmc_writel(pmc, value, PMC_IMPL_E_33V_PWR);
- } else {
- /* write-enable PMC_PWR_DET_VALUE[pad->voltage] */
+ if (pmc->soc->has_io_pad_wren) {
+ /* write-enable PMC_PWR_DET_VALUE[pad->ena_3v3] */
value = tegra_pmc_readl(pmc, PMC_PWR_DET);
- value |= BIT(pad->voltage);
+ value |= BIT(pad->ena_3v3);
tegra_pmc_writel(pmc, value, PMC_PWR_DET);
+ }
- /* update I/O voltage */
- value = tegra_pmc_readl(pmc, PMC_PWR_DET_VALUE);
+ value = tegra_pmc_readl(pmc, pad->offset);
- if (voltage == TEGRA_IO_PAD_VOLTAGE_1V8)
- value &= ~BIT(pad->voltage);
- else
- value |= BIT(pad->voltage);
+ if (voltage == TEGRA_IO_PAD_VOLTAGE_1V8) {
+ value &= ~BIT(pad->ena_3v3);
- tegra_pmc_writel(pmc, value, PMC_PWR_DET_VALUE);
+ if (pad->ena_1v8)
+ value |= pad->ena_1v8;
+ } else {
+ value |= BIT(pad->ena_3v3);
+
+ if (pad->ena_1v8)
+ value &= ~pad->ena_1v8;
}
+ tegra_pmc_writel(pmc, value, pad->offset);
+
mutex_unlock(&pmc->powergates_lock);
usleep_range(100, 250);
@@ -1930,22 +1958,16 @@ static int tegra_io_pad_set_voltage(struct tegra_pmc *pmc, enum tegra_io_pad id,
static int tegra_io_pad_get_voltage(struct tegra_pmc *pmc, enum tegra_io_pad id)
{
- const struct tegra_io_pad_soc *pad;
+ const struct tegra_io_pad_vctrl *pad;
u32 value;
- pad = tegra_io_pad_find(pmc, id);
+ pad = tegra_io_pad_vctrl_find(pmc, id);
if (!pad)
return -ENOENT;
- if (pad->voltage == UINT_MAX)
- return -ENOTSUPP;
-
- if (pmc->soc->has_impl_33v_pwr)
- value = tegra_pmc_readl(pmc, PMC_IMPL_E_33V_PWR);
- else
- value = tegra_pmc_readl(pmc, PMC_PWR_DET_VALUE);
+ value = tegra_pmc_readl(pmc, pad->offset);
- if ((value & BIT(pad->voltage)) == 0)
+ if ((value & BIT(pad->ena_3v3)) == 0)
return TEGRA_IO_PAD_VOLTAGE_1V8;
return TEGRA_IO_PAD_VOLTAGE_3V3;
@@ -2629,20 +2651,20 @@ static int tegra186_pmc_irq_set_wake(struct irq_data *data, unsigned int on)
bit = data->hwirq % 32;
/* clear wake status */
- writel(0x1, pmc->wake + WAKE_AOWAKE_STATUS_W(data->hwirq));
+ writel(0x1, pmc->wake + WAKE_AOWAKE_STATUS_W(pmc, data->hwirq));
/* route wake to tier 2 */
- value = readl(pmc->wake + WAKE_AOWAKE_TIER2_ROUTING(offset));
+ value = readl(pmc->wake + WAKE_AOWAKE_TIER2_ROUTING(pmc, offset));
if (!on)
value &= ~(1 << bit);
else
value |= 1 << bit;
- writel(value, pmc->wake + WAKE_AOWAKE_TIER2_ROUTING(offset));
+ writel(value, pmc->wake + WAKE_AOWAKE_TIER2_ROUTING(pmc, offset));
/* enable wakeup event */
- writel(!!on, pmc->wake + WAKE_AOWAKE_MASK_W(data->hwirq));
+ writel(!!on, pmc->wake + WAKE_AOWAKE_MASK_W(pmc, data->hwirq));
return 0;
}
@@ -3309,7 +3331,7 @@ static void wke_write_wake_levels(struct tegra_pmc *pmc)
static void wke_clear_sw_wake_status(struct tegra_pmc *pmc)
{
- wke_32kwritel(pmc, 1, WAKE_AOWAKE_SW_STATUS_W_0);
+ wke_32kwritel(pmc, 1, pmc->soc->regs->aowake_sw_status_w);
}
static void wke_read_sw_wake_status(struct tegra_pmc *pmc)
@@ -3322,7 +3344,7 @@ static void wke_read_sw_wake_status(struct tegra_pmc *pmc)
wke_clear_sw_wake_status(pmc);
- wke_32kwritel(pmc, 1, WAKE_LATCH_SW);
+ wke_32kwritel(pmc, 1, pmc->soc->regs->aowake_latch_sw);
/*
* WAKE_AOWAKE_SW_STATUS is edge triggered, so in order to
@@ -3340,12 +3362,12 @@ static void wke_read_sw_wake_status(struct tegra_pmc *pmc)
*/
udelay(300);
- wke_32kwritel(pmc, 0, WAKE_LATCH_SW);
+ wke_32kwritel(pmc, 0, pmc->soc->regs->aowake_latch_sw);
bitmap_zero(pmc->wake_sw_status_map, pmc->soc->max_wake_events);
for (i = 0; i < pmc->soc->max_wake_vectors; i++) {
- status = readl(pmc->wake + WAKE_AOWAKE_SW_STATUS(i));
+ status = readl(pmc->wake + WAKE_AOWAKE_SW_STATUS(pmc, i));
for_each_set_bit(wake, &status, 32)
set_bit(wake + (i * 32), pmc->wake_sw_status_map);
@@ -3359,11 +3381,12 @@ static void wke_clear_wake_status(struct tegra_pmc *pmc)
u32 mask;
for (i = 0; i < pmc->soc->max_wake_vectors; i++) {
- mask = readl(pmc->wake + WAKE_AOWAKE_TIER2_ROUTING(i));
- status = readl(pmc->wake + WAKE_AOWAKE_STATUS_R(i)) & mask;
+ mask = readl(pmc->wake + WAKE_AOWAKE_TIER2_ROUTING(pmc, i));
+ status = readl(pmc->wake + WAKE_AOWAKE_STATUS_R(pmc, i)) & mask;
for_each_set_bit(wake, &status, 32)
- wke_32kwritel(pmc, 0x1, WAKE_AOWAKE_STATUS_W((i * 32) + wake));
+ wke_32kwritel(pmc, 0x1, WAKE_AOWAKE_STATUS_W(pmc,
+ (i * 32) + wake));
}
}
@@ -3374,8 +3397,9 @@ static void tegra186_pmc_wake_syscore_resume(void *data)
u32 mask;
for (i = 0; i < pmc->soc->max_wake_vectors; i++) {
- mask = readl(pmc->wake + WAKE_AOWAKE_TIER2_ROUTING(i));
- pmc->wake_status[i] = readl(pmc->wake + WAKE_AOWAKE_STATUS_R(i)) & mask;
+ mask = readl(pmc->wake + WAKE_AOWAKE_TIER2_ROUTING(pmc, i));
+ pmc->wake_status[i] = readl(pmc->wake +
+ WAKE_AOWAKE_STATUS_R(pmc, i)) & mask;
}
/* Schedule IRQ work to process wake IRQs (if any) */
@@ -3523,7 +3547,7 @@ static const struct tegra_pmc_soc tegra20_pmc_soc = {
.has_tsense_reset = false,
.has_gpu_clamps = false,
.needs_mbist_war = false,
- .has_impl_33v_pwr = false,
+ .has_io_pad_wren = true,
.maybe_tz_only = false,
.num_io_pads = 0,
.io_pads = NULL,
@@ -3585,7 +3609,7 @@ static const struct tegra_pmc_soc tegra30_pmc_soc = {
.has_tsense_reset = true,
.has_gpu_clamps = false,
.needs_mbist_war = false,
- .has_impl_33v_pwr = false,
+ .has_io_pad_wren = true,
.maybe_tz_only = false,
.num_io_pads = 0,
.io_pads = NULL,
@@ -3635,7 +3659,7 @@ static const u8 tegra114_cpu_powergates[] = {
};
static const struct tegra_pmc_soc tegra114_pmc_soc = {
- .supports_core_domain = false,
+ .supports_core_domain = true,
.num_powergates = ARRAY_SIZE(tegra114_powergates),
.powergates = tegra114_powergates,
.num_cpu_powergates = ARRAY_SIZE(tegra114_cpu_powergates),
@@ -3643,7 +3667,7 @@ static const struct tegra_pmc_soc tegra114_pmc_soc = {
.has_tsense_reset = true,
.has_gpu_clamps = false,
.needs_mbist_war = false,
- .has_impl_33v_pwr = false,
+ .has_io_pad_wren = true,
.maybe_tz_only = false,
.num_io_pads = 0,
.io_pads = NULL,
@@ -3697,16 +3721,23 @@ static const u8 tegra124_cpu_powergates[] = {
TEGRA_POWERGATE_CPU3,
};
-#define TEGRA_IO_PAD(_id, _dpd, _request, _status, _voltage, _name) \
+#define TEGRA_IO_PAD(_id, _dpd, _request, _status, _name) \
((struct tegra_io_pad_soc) { \
.id = (_id), \
.dpd = (_dpd), \
.request = (_request), \
.status = (_status), \
- .voltage = (_voltage), \
.name = (_name), \
})
+#define TEGRA_IO_PAD_VCTRL(_id, _offset, _ena_3v3) \
+ ((struct tegra_io_pad_vctrl) { \
+ .id = (_id), \
+ .offset = (_offset), \
+ .ena_3v3 = (_ena_3v3), \
+ .ena_1v8 = 0, \
+ })
+
#define TEGRA_IO_PIN_DESC(_id, _name) \
((struct pinctrl_pin_desc) { \
.number = (_id), \
@@ -3714,36 +3745,36 @@ static const u8 tegra124_cpu_powergates[] = {
})
static const struct tegra_io_pad_soc tegra124_io_pads[] = {
- TEGRA_IO_PAD(TEGRA_IO_PAD_AUDIO, 17, 0x1b8, 0x1bc, UINT_MAX, "audio"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_BB, 15, 0x1b8, 0x1bc, UINT_MAX, "bb"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_CAM, 4, 0x1c0, 0x1c4, UINT_MAX, "cam"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_COMP, 22, 0x1b8, 0x1bc, UINT_MAX, "comp"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_CSIA, 0, 0x1b8, 0x1bc, UINT_MAX, "csia"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_CSIB, 1, 0x1b8, 0x1bc, UINT_MAX, "csib"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_CSIE, 12, 0x1c0, 0x1c4, UINT_MAX, "csie"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_DSI, 2, 0x1b8, 0x1bc, UINT_MAX, "dsi"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_DSIB, 7, 0x1c0, 0x1c4, UINT_MAX, "dsib"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_DSIC, 8, 0x1c0, 0x1c4, UINT_MAX, "dsic"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_DSID, 9, 0x1c0, 0x1c4, UINT_MAX, "dsid"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_HDMI, 28, 0x1b8, 0x1bc, UINT_MAX, "hdmi"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_HSIC, 19, 0x1b8, 0x1bc, UINT_MAX, "hsic"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_HV, 6, 0x1c0, 0x1c4, UINT_MAX, "hv"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_LVDS, 25, 0x1c0, 0x1c4, UINT_MAX, "lvds"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_MIPI_BIAS, 3, 0x1b8, 0x1bc, UINT_MAX, "mipi-bias"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_NAND, 13, 0x1b8, 0x1bc, UINT_MAX, "nand"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_BIAS, 4, 0x1b8, 0x1bc, UINT_MAX, "pex-bias"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CLK1, 5, 0x1b8, 0x1bc, UINT_MAX, "pex-clk1"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CLK2, 6, 0x1b8, 0x1bc, UINT_MAX, "pex-clk2"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CNTRL, 0, 0x1c0, 0x1c4, UINT_MAX, "pex-cntrl"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC1, 1, 0x1c0, 0x1c4, UINT_MAX, "sdmmc1"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC3, 2, 0x1c0, 0x1c4, UINT_MAX, "sdmmc3"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC4, 3, 0x1c0, 0x1c4, UINT_MAX, "sdmmc4"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_SYS_DDC, 26, 0x1c0, 0x1c4, UINT_MAX, "sys_ddc"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_UART, 14, 0x1b8, 0x1bc, UINT_MAX, "uart"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_USB0, 9, 0x1b8, 0x1bc, UINT_MAX, "usb0"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_USB1, 10, 0x1b8, 0x1bc, UINT_MAX, "usb1"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_USB2, 11, 0x1b8, 0x1bc, UINT_MAX, "usb2"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_USB_BIAS, 12, 0x1b8, 0x1bc, UINT_MAX, "usb_bias"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_AUDIO, 17, 0x1b8, 0x1bc, "audio"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_BB, 15, 0x1b8, 0x1bc, "bb"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_CAM, 4, 0x1c0, 0x1c4, "cam"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_COMP, 22, 0x1b8, 0x1bc, "comp"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_CSIA, 0, 0x1b8, 0x1bc, "csia"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_CSIB, 1, 0x1b8, 0x1bc, "csib"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_CSIE, 12, 0x1c0, 0x1c4, "csie"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_DSI, 2, 0x1b8, 0x1bc, "dsi"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_DSIB, 7, 0x1c0, 0x1c4, "dsib"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_DSIC, 8, 0x1c0, 0x1c4, "dsic"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_DSID, 9, 0x1c0, 0x1c4, "dsid"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_HDMI, 28, 0x1b8, 0x1bc, "hdmi"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_HSIC, 19, 0x1b8, 0x1bc, "hsic"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_HV, 6, 0x1c0, 0x1c4, "hv"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_LVDS, 25, 0x1c0, 0x1c4, "lvds"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_MIPI_BIAS, 3, 0x1b8, 0x1bc, "mipi-bias"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_NAND, 13, 0x1b8, 0x1bc, "nand"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_BIAS, 4, 0x1b8, 0x1bc, "pex-bias"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CLK1, 5, 0x1b8, 0x1bc, "pex-clk1"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CLK2, 6, 0x1b8, 0x1bc, "pex-clk2"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CNTRL, 0, 0x1c0, 0x1c4, "pex-cntrl"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC1, 1, 0x1c0, 0x1c4, "sdmmc1"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC3, 2, 0x1c0, 0x1c4, "sdmmc3"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC4, 3, 0x1c0, 0x1c4, "sdmmc4"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_SYS_DDC, 26, 0x1c0, 0x1c4, "sys_ddc"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_UART, 14, 0x1b8, 0x1bc, "uart"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_USB0, 9, 0x1b8, 0x1bc, "usb0"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_USB1, 10, 0x1b8, 0x1bc, "usb1"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_USB2, 11, 0x1b8, 0x1bc, "usb2"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_USB_BIAS, 12, 0x1b8, 0x1bc, "usb_bias"),
};
static const struct pinctrl_pin_desc tegra124_pin_descs[] = {
@@ -3788,7 +3819,7 @@ static const struct tegra_pmc_soc tegra124_pmc_soc = {
.has_tsense_reset = true,
.has_gpu_clamps = true,
.needs_mbist_war = false,
- .has_impl_33v_pwr = false,
+ .has_io_pad_wren = true,
.maybe_tz_only = false,
.num_io_pads = ARRAY_SIZE(tegra124_io_pads),
.io_pads = tegra124_io_pads,
@@ -3844,46 +3875,60 @@ static const u8 tegra210_cpu_powergates[] = {
};
static const struct tegra_io_pad_soc tegra210_io_pads[] = {
- TEGRA_IO_PAD(TEGRA_IO_PAD_AUDIO, 17, 0x1b8, 0x1bc, 5, "audio"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_AUDIO_HV, 29, 0x1c0, 0x1c4, 18, "audio-hv"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_CAM, 4, 0x1c0, 0x1c4, 10, "cam"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_CSIA, 0, 0x1b8, 0x1bc, UINT_MAX, "csia"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_CSIB, 1, 0x1b8, 0x1bc, UINT_MAX, "csib"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_CSIC, 10, 0x1c0, 0x1c4, UINT_MAX, "csic"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_CSID, 11, 0x1c0, 0x1c4, UINT_MAX, "csid"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_CSIE, 12, 0x1c0, 0x1c4, UINT_MAX, "csie"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_CSIF, 13, 0x1c0, 0x1c4, UINT_MAX, "csif"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_DBG, 25, 0x1b8, 0x1bc, 19, "dbg"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_DEBUG_NONAO, 26, 0x1b8, 0x1bc, UINT_MAX, "debug-nonao"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_DMIC, 18, 0x1c0, 0x1c4, 20, "dmic"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_DP, 19, 0x1c0, 0x1c4, UINT_MAX, "dp"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_DSI, 2, 0x1b8, 0x1bc, UINT_MAX, "dsi"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_DSIB, 7, 0x1c0, 0x1c4, UINT_MAX, "dsib"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_DSIC, 8, 0x1c0, 0x1c4, UINT_MAX, "dsic"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_DSID, 9, 0x1c0, 0x1c4, UINT_MAX, "dsid"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_EMMC, 3, 0x1c0, 0x1c4, UINT_MAX, "emmc"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_EMMC2, 5, 0x1c0, 0x1c4, UINT_MAX, "emmc2"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_GPIO, 27, 0x1b8, 0x1bc, 21, "gpio"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_HDMI, 28, 0x1b8, 0x1bc, UINT_MAX, "hdmi"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_HSIC, 19, 0x1b8, 0x1bc, UINT_MAX, "hsic"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_LVDS, 25, 0x1c0, 0x1c4, UINT_MAX, "lvds"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_MIPI_BIAS, 3, 0x1b8, 0x1bc, UINT_MAX, "mipi-bias"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_BIAS, 4, 0x1b8, 0x1bc, UINT_MAX, "pex-bias"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CLK1, 5, 0x1b8, 0x1bc, UINT_MAX, "pex-clk1"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CLK2, 6, 0x1b8, 0x1bc, UINT_MAX, "pex-clk2"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CNTRL, UINT_MAX, UINT_MAX, UINT_MAX, 11, "pex-cntrl"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC1, 1, 0x1c0, 0x1c4, 12, "sdmmc1"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC3, 2, 0x1c0, 0x1c4, 13, "sdmmc3"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_SPI, 14, 0x1c0, 0x1c4, 22, "spi"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_SPI_HV, 15, 0x1c0, 0x1c4, 23, "spi-hv"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_UART, 14, 0x1b8, 0x1bc, 2, "uart"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_USB0, 9, 0x1b8, 0x1bc, UINT_MAX, "usb0"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_USB1, 10, 0x1b8, 0x1bc, UINT_MAX, "usb1"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_USB2, 11, 0x1b8, 0x1bc, UINT_MAX, "usb2"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_USB3, 18, 0x1b8, 0x1bc, UINT_MAX, "usb3"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_USB_BIAS, 12, 0x1b8, 0x1bc, UINT_MAX, "usb-bias"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_AUDIO, 17, 0x1b8, 0x1bc, "audio"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_AUDIO_HV, 29, 0x1c0, 0x1c4, "audio-hv"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_CAM, 4, 0x1c0, 0x1c4, "cam"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_CSIA, 0, 0x1b8, 0x1bc, "csia"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_CSIB, 1, 0x1b8, 0x1bc, "csib"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_CSIC, 10, 0x1c0, 0x1c4, "csic"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_CSID, 11, 0x1c0, 0x1c4, "csid"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_CSIE, 12, 0x1c0, 0x1c4, "csie"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_CSIF, 13, 0x1c0, 0x1c4, "csif"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_DBG, 25, 0x1b8, 0x1bc, "dbg"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_DEBUG_NONAO, 26, 0x1b8, 0x1bc, "debug-nonao"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_DMIC, 18, 0x1c0, 0x1c4, "dmic"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_DP, 19, 0x1c0, 0x1c4, "dp"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_DSI, 2, 0x1b8, 0x1bc, "dsi"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_DSIB, 7, 0x1c0, 0x1c4, "dsib"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_DSIC, 8, 0x1c0, 0x1c4, "dsic"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_DSID, 9, 0x1c0, 0x1c4, "dsid"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_EMMC, 3, 0x1c0, 0x1c4, "emmc"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_EMMC2, 5, 0x1c0, 0x1c4, "emmc2"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_GPIO, 27, 0x1b8, 0x1bc, "gpio"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_HDMI, 28, 0x1b8, 0x1bc, "hdmi"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_HSIC, 19, 0x1b8, 0x1bc, "hsic"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_LVDS, 25, 0x1c0, 0x1c4, "lvds"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_MIPI_BIAS, 3, 0x1b8, 0x1bc, "mipi-bias"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_BIAS, 4, 0x1b8, 0x1bc, "pex-bias"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CLK1, 5, 0x1b8, 0x1bc, "pex-clk1"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CLK2, 6, 0x1b8, 0x1bc, "pex-clk2"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CNTRL, UINT_MAX, UINT_MAX, UINT_MAX, "pex-cntrl"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC1, 1, 0x1c0, 0x1c4, "sdmmc1"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC3, 2, 0x1c0, 0x1c4, "sdmmc3"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_SPI, 14, 0x1c0, 0x1c4, "spi"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_SPI_HV, 15, 0x1c0, 0x1c4, "spi-hv"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_UART, 14, 0x1b8, 0x1bc, "uart"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_USB0, 9, 0x1b8, 0x1bc, "usb0"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_USB1, 10, 0x1b8, 0x1bc, "usb1"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_USB2, 11, 0x1b8, 0x1bc, "usb2"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_USB3, 18, 0x1b8, 0x1bc, "usb3"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_USB_BIAS, 12, 0x1b8, 0x1bc, "usb-bias"),
};
+static const struct tegra_io_pad_vctrl tegra210_io_pad_vctrls[] = {
+ TEGRA_IO_PAD_VCTRL(TEGRA_IO_PAD_AUDIO, PMC_PWR_DET_VALUE, 5),
+ TEGRA_IO_PAD_VCTRL(TEGRA_IO_PAD_AUDIO_HV, PMC_PWR_DET_VALUE, 18),
+ TEGRA_IO_PAD_VCTRL(TEGRA_IO_PAD_CAM, PMC_PWR_DET_VALUE, 10),
+ TEGRA_IO_PAD_VCTRL(TEGRA_IO_PAD_DBG, PMC_PWR_DET_VALUE, 19),
+ TEGRA_IO_PAD_VCTRL(TEGRA_IO_PAD_DMIC, PMC_PWR_DET_VALUE, 20),
+ TEGRA_IO_PAD_VCTRL(TEGRA_IO_PAD_GPIO, PMC_PWR_DET_VALUE, 21),
+ TEGRA_IO_PAD_VCTRL(TEGRA_IO_PAD_PEX_CNTRL, PMC_PWR_DET_VALUE, 11),
+ TEGRA_IO_PAD_VCTRL(TEGRA_IO_PAD_SDMMC1, PMC_PWR_DET_VALUE, 12),
+ TEGRA_IO_PAD_VCTRL(TEGRA_IO_PAD_SDMMC3, PMC_PWR_DET_VALUE, 13),
+ TEGRA_IO_PAD_VCTRL(TEGRA_IO_PAD_SPI, PMC_PWR_DET_VALUE, 22),
+ TEGRA_IO_PAD_VCTRL(TEGRA_IO_PAD_SPI_HV, PMC_PWR_DET_VALUE, 23),
+ TEGRA_IO_PAD_VCTRL(TEGRA_IO_PAD_UART, PMC_PWR_DET_VALUE, 2),
+};
static const struct pinctrl_pin_desc tegra210_pin_descs[] = {
TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_AUDIO, "audio"),
TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_AUDIO_HV, "audio-hv"),
@@ -3948,10 +3993,12 @@ static const struct tegra_pmc_soc tegra210_pmc_soc = {
.has_tsense_reset = true,
.has_gpu_clamps = true,
.needs_mbist_war = true,
- .has_impl_33v_pwr = false,
+ .has_io_pad_wren = true,
.maybe_tz_only = true,
.num_io_pads = ARRAY_SIZE(tegra210_io_pads),
.io_pads = tegra210_io_pads,
+ .num_io_pad_vctrls = ARRAY_SIZE(tegra210_io_pad_vctrls),
+ .io_pad_vctrls = tegra210_io_pad_vctrls,
.num_pin_descs = ARRAY_SIZE(tegra210_pin_descs),
.pin_descs = tegra210_pin_descs,
.regs = &tegra20_pmc_regs,
@@ -3974,44 +4021,53 @@ static const struct tegra_pmc_soc tegra210_pmc_soc = {
};
static const struct tegra_io_pad_soc tegra186_io_pads[] = {
- TEGRA_IO_PAD(TEGRA_IO_PAD_CSIA, 0, 0x74, 0x78, UINT_MAX, "csia"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_CSIB, 1, 0x74, 0x78, UINT_MAX, "csib"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_DSI, 2, 0x74, 0x78, UINT_MAX, "dsi"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_MIPI_BIAS, 3, 0x74, 0x78, UINT_MAX, "mipi-bias"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CLK_BIAS, 4, 0x74, 0x78, UINT_MAX, "pex-clk-bias"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CLK3, 5, 0x74, 0x78, UINT_MAX, "pex-clk3"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CLK2, 6, 0x74, 0x78, UINT_MAX, "pex-clk2"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CLK1, 7, 0x74, 0x78, UINT_MAX, "pex-clk1"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_USB0, 9, 0x74, 0x78, UINT_MAX, "usb0"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_USB1, 10, 0x74, 0x78, UINT_MAX, "usb1"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_USB2, 11, 0x74, 0x78, UINT_MAX, "usb2"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_USB_BIAS, 12, 0x74, 0x78, UINT_MAX, "usb-bias"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_UART, 14, 0x74, 0x78, UINT_MAX, "uart"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_AUDIO, 17, 0x74, 0x78, UINT_MAX, "audio"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_HSIC, 19, 0x74, 0x78, UINT_MAX, "hsic"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_DBG, 25, 0x74, 0x78, UINT_MAX, "dbg"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_HDMI_DP0, 28, 0x74, 0x78, UINT_MAX, "hdmi-dp0"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_HDMI_DP1, 29, 0x74, 0x78, UINT_MAX, "hdmi-dp1"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CNTRL, 0, 0x7c, 0x80, UINT_MAX, "pex-cntrl"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC2_HV, 2, 0x7c, 0x80, 5, "sdmmc2-hv"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC4, 4, 0x7c, 0x80, UINT_MAX, "sdmmc4"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_CAM, 6, 0x7c, 0x80, UINT_MAX, "cam"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_DSIB, 8, 0x7c, 0x80, UINT_MAX, "dsib"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_DSIC, 9, 0x7c, 0x80, UINT_MAX, "dsic"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_DSID, 10, 0x7c, 0x80, UINT_MAX, "dsid"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_CSIC, 11, 0x7c, 0x80, UINT_MAX, "csic"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_CSID, 12, 0x7c, 0x80, UINT_MAX, "csid"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_CSIE, 13, 0x7c, 0x80, UINT_MAX, "csie"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_CSIF, 14, 0x7c, 0x80, UINT_MAX, "csif"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_SPI, 15, 0x7c, 0x80, UINT_MAX, "spi"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_UFS, 17, 0x7c, 0x80, UINT_MAX, "ufs"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_DMIC_HV, 20, 0x7c, 0x80, 2, "dmic-hv"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_EDP, 21, 0x7c, 0x80, UINT_MAX, "edp"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC1_HV, 23, 0x7c, 0x80, 4, "sdmmc1-hv"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC3_HV, 24, 0x7c, 0x80, 6, "sdmmc3-hv"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_CONN, 28, 0x7c, 0x80, UINT_MAX, "conn"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_AUDIO_HV, 29, 0x7c, 0x80, 1, "audio-hv"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_AO_HV, UINT_MAX, UINT_MAX, UINT_MAX, 0, "ao-hv"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_CSIA, 0, 0x74, 0x78, "csia"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_CSIB, 1, 0x74, 0x78, "csib"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_DSI, 2, 0x74, 0x78, "dsi"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_MIPI_BIAS, 3, 0x74, 0x78, "mipi-bias"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CLK_BIAS, 4, 0x74, 0x78, "pex-clk-bias"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CLK3, 5, 0x74, 0x78, "pex-clk3"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CLK2, 6, 0x74, 0x78, "pex-clk2"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CLK1, 7, 0x74, 0x78, "pex-clk1"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_USB0, 9, 0x74, 0x78, "usb0"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_USB1, 10, 0x74, 0x78, "usb1"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_USB2, 11, 0x74, 0x78, "usb2"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_USB_BIAS, 12, 0x74, 0x78, "usb-bias"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_UART, 14, 0x74, 0x78, "uart"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_AUDIO, 17, 0x74, 0x78, "audio"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_HSIC, 19, 0x74, 0x78, "hsic"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_DBG, 25, 0x74, 0x78, "dbg"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_HDMI_DP0, 28, 0x74, 0x78, "hdmi-dp0"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_HDMI_DP1, 29, 0x74, 0x78, "hdmi-dp1"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CNTRL, 0, 0x7c, 0x80, "pex-cntrl"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC2_HV, 2, 0x7c, 0x80, "sdmmc2-hv"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC4, 4, 0x7c, 0x80, "sdmmc4"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_CAM, 6, 0x7c, 0x80, "cam"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_DSIB, 8, 0x7c, 0x80, "dsib"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_DSIC, 9, 0x7c, 0x80, "dsic"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_DSID, 10, 0x7c, 0x80, "dsid"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_CSIC, 11, 0x7c, 0x80, "csic"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_CSID, 12, 0x7c, 0x80, "csid"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_CSIE, 13, 0x7c, 0x80, "csie"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_CSIF, 14, 0x7c, 0x80, "csif"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_SPI, 15, 0x7c, 0x80, "spi"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_UFS, 17, 0x7c, 0x80, "ufs"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_DMIC_HV, 20, 0x7c, 0x80, "dmic-hv"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_EDP, 21, 0x7c, 0x80, "edp"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC1_HV, 23, 0x7c, 0x80, "sdmmc1-hv"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC3_HV, 24, 0x7c, 0x80, "sdmmc3-hv"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_CONN, 28, 0x7c, 0x80, "conn"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_AUDIO_HV, 29, 0x7c, 0x80, "audio-hv"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_AO_HV, UINT_MAX, UINT_MAX, UINT_MAX, "ao-hv"),
+};
+
+static const struct tegra_io_pad_vctrl tegra186_io_pad_vctrls[] = {
+ TEGRA_IO_PAD_VCTRL(TEGRA_IO_PAD_SDMMC2_HV, PMC_IMPL_E_33V_PWR, 5),
+ TEGRA_IO_PAD_VCTRL(TEGRA_IO_PAD_DMIC_HV, PMC_IMPL_E_33V_PWR, 2),
+ TEGRA_IO_PAD_VCTRL(TEGRA_IO_PAD_SDMMC1_HV, PMC_IMPL_E_33V_PWR, 4),
+ TEGRA_IO_PAD_VCTRL(TEGRA_IO_PAD_SDMMC3_HV, PMC_IMPL_E_33V_PWR, 6),
+ TEGRA_IO_PAD_VCTRL(TEGRA_IO_PAD_AUDIO_HV, PMC_IMPL_E_33V_PWR, 1),
+ TEGRA_IO_PAD_VCTRL(TEGRA_IO_PAD_AO_HV, PMC_IMPL_E_33V_PWR, 0),
};
static const struct pinctrl_pin_desc tegra186_pin_descs[] = {
@@ -4062,6 +4118,14 @@ static const struct tegra_pmc_regs tegra186_pmc_regs = {
.rst_source_mask = 0x3c,
.rst_level_shift = 0x0,
.rst_level_mask = 0x3,
+ .aowake_mask_w = 0x180,
+ .aowake_status_w = 0x30c,
+ .aowake_status_r = 0x48c,
+ .aowake_tier2_routing = 0x4cc,
+ .aowake_sw_status_w = 0x49c,
+ .aowake_sw_status = 0x4a0,
+ .aowake_latch_sw = 0x498,
+ .aowake_ctrl = 0x4f4,
};
static void tegra186_pmc_init(struct tegra_pmc *pmc)
@@ -4094,14 +4158,14 @@ static void tegra186_pmc_setup_irq_polarity(struct tegra_pmc *pmc,
return;
}
- value = readl(wake + WAKE_AOWAKE_CTRL);
+ value = readl(wake + pmc->soc->regs->aowake_ctrl);
if (invert)
value |= WAKE_AOWAKE_CTRL_INTR_POLARITY;
else
value &= ~WAKE_AOWAKE_CTRL_INTR_POLARITY;
- writel(value, wake + WAKE_AOWAKE_CTRL);
+ writel(value, wake + pmc->soc->regs->aowake_ctrl);
iounmap(wake);
}
@@ -4143,10 +4207,12 @@ static const struct tegra_pmc_soc tegra186_pmc_soc = {
.has_tsense_reset = false,
.has_gpu_clamps = false,
.needs_mbist_war = false,
- .has_impl_33v_pwr = true,
+ .has_io_pad_wren = false,
.maybe_tz_only = false,
.num_io_pads = ARRAY_SIZE(tegra186_io_pads),
.io_pads = tegra186_io_pads,
+ .num_io_pad_vctrls = ARRAY_SIZE(tegra186_io_pad_vctrls),
+ .io_pad_vctrls = tegra186_io_pad_vctrls,
.num_pin_descs = ARRAY_SIZE(tegra186_pin_descs),
.pin_descs = tegra186_pin_descs,
.regs = &tegra186_pmc_regs,
@@ -4171,55 +4237,62 @@ static const struct tegra_pmc_soc tegra186_pmc_soc = {
};
static const struct tegra_io_pad_soc tegra194_io_pads[] = {
- TEGRA_IO_PAD(TEGRA_IO_PAD_CSIA, 0, 0x74, 0x78, UINT_MAX, "csia"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_CSIB, 1, 0x74, 0x78, UINT_MAX, "csib"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_MIPI_BIAS, 3, 0x74, 0x78, UINT_MAX, "mipi-bias"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CLK_BIAS, 4, 0x74, 0x78, UINT_MAX, "pex-clk-bias"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CLK3, 5, 0x74, 0x78, UINT_MAX, "pex-clk3"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CLK2, 6, 0x74, 0x78, UINT_MAX, "pex-clk2"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CLK1, 7, 0x74, 0x78, UINT_MAX, "pex-clk1"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_EQOS, 8, 0x74, 0x78, UINT_MAX, "eqos"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CLK_2_BIAS, 9, 0x74, 0x78, UINT_MAX, "pex-clk-2-bias"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CLK_2, 10, 0x74, 0x78, UINT_MAX, "pex-clk-2"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_DAP3, 11, 0x74, 0x78, UINT_MAX, "dap3"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_DAP5, 12, 0x74, 0x78, UINT_MAX, "dap5"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_UART, 14, 0x74, 0x78, UINT_MAX, "uart"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_PWR_CTL, 15, 0x74, 0x78, UINT_MAX, "pwr-ctl"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_SOC_GPIO53, 16, 0x74, 0x78, UINT_MAX, "soc-gpio53"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_AUDIO, 17, 0x74, 0x78, UINT_MAX, "audio"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_GP_PWM2, 18, 0x74, 0x78, UINT_MAX, "gp-pwm2"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_GP_PWM3, 19, 0x74, 0x78, UINT_MAX, "gp-pwm3"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_SOC_GPIO12, 20, 0x74, 0x78, UINT_MAX, "soc-gpio12"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_SOC_GPIO13, 21, 0x74, 0x78, UINT_MAX, "soc-gpio13"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_SOC_GPIO10, 22, 0x74, 0x78, UINT_MAX, "soc-gpio10"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_UART4, 23, 0x74, 0x78, UINT_MAX, "uart4"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_UART5, 24, 0x74, 0x78, UINT_MAX, "uart5"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_DBG, 25, 0x74, 0x78, UINT_MAX, "dbg"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_HDMI_DP3, 26, 0x74, 0x78, UINT_MAX, "hdmi-dp3"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_HDMI_DP2, 27, 0x74, 0x78, UINT_MAX, "hdmi-dp2"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_HDMI_DP0, 28, 0x74, 0x78, UINT_MAX, "hdmi-dp0"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_HDMI_DP1, 29, 0x74, 0x78, UINT_MAX, "hdmi-dp1"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CNTRL, 0, 0x7c, 0x80, UINT_MAX, "pex-cntrl"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CTL2, 1, 0x7c, 0x80, UINT_MAX, "pex-ctl2"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_L0_RST, 2, 0x7c, 0x80, UINT_MAX, "pex-l0-rst"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_L1_RST, 3, 0x7c, 0x80, UINT_MAX, "pex-l1-rst"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC4, 4, 0x7c, 0x80, UINT_MAX, "sdmmc4"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_L5_RST, 5, 0x7c, 0x80, UINT_MAX, "pex-l5-rst"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_CAM, 6, 0x7c, 0x80, UINT_MAX, "cam"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_CSIC, 11, 0x7c, 0x80, UINT_MAX, "csic"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_CSID, 12, 0x7c, 0x80, UINT_MAX, "csid"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_CSIE, 13, 0x7c, 0x80, UINT_MAX, "csie"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_CSIF, 14, 0x7c, 0x80, UINT_MAX, "csif"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_SPI, 15, 0x7c, 0x80, UINT_MAX, "spi"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_UFS, 17, 0x7c, 0x80, UINT_MAX, "ufs"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_CSIG, 18, 0x7c, 0x80, UINT_MAX, "csig"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_CSIH, 19, 0x7c, 0x80, UINT_MAX, "csih"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_EDP, 21, 0x7c, 0x80, UINT_MAX, "edp"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC1_HV, 23, 0x7c, 0x80, 4, "sdmmc1-hv"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC3_HV, 24, 0x7c, 0x80, 6, "sdmmc3-hv"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_CONN, 28, 0x7c, 0x80, UINT_MAX, "conn"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_AUDIO_HV, 29, 0x7c, 0x80, 1, "audio-hv"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_AO_HV, UINT_MAX, UINT_MAX, UINT_MAX, 0, "ao-hv"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_CSIA, 0, 0x74, 0x78, "csia"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_CSIB, 1, 0x74, 0x78, "csib"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_MIPI_BIAS, 3, 0x74, 0x78, "mipi-bias"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CLK_BIAS, 4, 0x74, 0x78, "pex-clk-bias"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CLK3, 5, 0x74, 0x78, "pex-clk3"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CLK2, 6, 0x74, 0x78, "pex-clk2"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CLK1, 7, 0x74, 0x78, "pex-clk1"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_EQOS, 8, 0x74, 0x78, "eqos"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CLK_2_BIAS, 9, 0x74, 0x78, "pex-clk-2-bias"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CLK_2, 10, 0x74, 0x78, "pex-clk-2"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_DAP3, 11, 0x74, 0x78, "dap3"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_DAP5, 12, 0x74, 0x78, "dap5"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_UART, 14, 0x74, 0x78, "uart"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_PWR_CTL, 15, 0x74, 0x78, "pwr-ctl"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_SOC_GPIO53, 16, 0x74, 0x78, "soc-gpio53"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_AUDIO, 17, 0x74, 0x78, "audio"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_GP_PWM2, 18, 0x74, 0x78, "gp-pwm2"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_GP_PWM3, 19, 0x74, 0x78, "gp-pwm3"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_SOC_GPIO12, 20, 0x74, 0x78, "soc-gpio12"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_SOC_GPIO13, 21, 0x74, 0x78, "soc-gpio13"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_SOC_GPIO10, 22, 0x74, 0x78, "soc-gpio10"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_UART4, 23, 0x74, 0x78, "uart4"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_UART5, 24, 0x74, 0x78, "uart5"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_DBG, 25, 0x74, 0x78, "dbg"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_HDMI_DP3, 26, 0x74, 0x78, "hdmi-dp3"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_HDMI_DP2, 27, 0x74, 0x78, "hdmi-dp2"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_HDMI_DP0, 28, 0x74, 0x78, "hdmi-dp0"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_HDMI_DP1, 29, 0x74, 0x78, "hdmi-dp1"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CNTRL, 0, 0x7c, 0x80, "pex-cntrl"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_CTL2, 1, 0x7c, 0x80, "pex-ctl2"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_L0_RST, 2, 0x7c, 0x80, "pex-l0-rst"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_L1_RST, 3, 0x7c, 0x80, "pex-l1-rst"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC4, 4, 0x7c, 0x80, "sdmmc4"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_PEX_L5_RST, 5, 0x7c, 0x80, "pex-l5-rst"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_CAM, 6, 0x7c, 0x80, "cam"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_CSIC, 11, 0x7c, 0x80, "csic"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_CSID, 12, 0x7c, 0x80, "csid"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_CSIE, 13, 0x7c, 0x80, "csie"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_CSIF, 14, 0x7c, 0x80, "csif"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_SPI, 15, 0x7c, 0x80, "spi"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_UFS, 17, 0x7c, 0x80, "ufs"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_CSIG, 18, 0x7c, 0x80, "csig"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_CSIH, 19, 0x7c, 0x80, "csih"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_EDP, 21, 0x7c, 0x80, "edp"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC1_HV, 23, 0x7c, 0x80, "sdmmc1-hv"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC3_HV, 24, 0x7c, 0x80, "sdmmc3-hv"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_CONN, 28, 0x7c, 0x80, "conn"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_AUDIO_HV, 29, 0x7c, 0x80, "audio-hv"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_AO_HV, UINT_MAX, UINT_MAX, UINT_MAX, "ao-hv"),
+};
+
+static const struct tegra_io_pad_vctrl tegra194_io_pad_vctrls[] = {
+ TEGRA_IO_PAD_VCTRL(TEGRA_IO_PAD_SDMMC1_HV, PMC_IMPL_E_33V_PWR, 4),
+ TEGRA_IO_PAD_VCTRL(TEGRA_IO_PAD_SDMMC3_HV, PMC_IMPL_E_33V_PWR, 6),
+ TEGRA_IO_PAD_VCTRL(TEGRA_IO_PAD_AUDIO_HV, PMC_IMPL_E_33V_PWR, 1),
+ TEGRA_IO_PAD_VCTRL(TEGRA_IO_PAD_AO_HV, PMC_IMPL_E_33V_PWR, 0),
};
static const struct pinctrl_pin_desc tegra194_pin_descs[] = {
@@ -4281,6 +4354,14 @@ static const struct tegra_pmc_regs tegra194_pmc_regs = {
.rst_source_mask = 0x7c,
.rst_level_shift = 0x0,
.rst_level_mask = 0x3,
+ .aowake_mask_w = 0x180,
+ .aowake_status_w = 0x30c,
+ .aowake_status_r = 0x48c,
+ .aowake_tier2_routing = 0x4cc,
+ .aowake_sw_status_w = 0x49c,
+ .aowake_sw_status = 0x4a0,
+ .aowake_latch_sw = 0x498,
+ .aowake_ctrl = 0x4f4,
};
static const char * const tegra194_reset_sources[] = {
@@ -4330,10 +4411,12 @@ static const struct tegra_pmc_soc tegra194_pmc_soc = {
.has_tsense_reset = false,
.has_gpu_clamps = false,
.needs_mbist_war = false,
- .has_impl_33v_pwr = true,
+ .has_io_pad_wren = false,
.maybe_tz_only = false,
.num_io_pads = ARRAY_SIZE(tegra194_io_pads),
.io_pads = tegra194_io_pads,
+ .num_io_pad_vctrls = ARRAY_SIZE(tegra194_io_pad_vctrls),
+ .io_pad_vctrls = tegra194_io_pad_vctrls,
.num_pin_descs = ARRAY_SIZE(tegra194_pin_descs),
.pin_descs = tegra194_pin_descs,
.regs = &tegra194_pmc_regs,
@@ -4358,21 +4441,28 @@ static const struct tegra_pmc_soc tegra194_pmc_soc = {
};
static const struct tegra_io_pad_soc tegra234_io_pads[] = {
- TEGRA_IO_PAD(TEGRA_IO_PAD_CSIA, 0, 0xe0c0, 0xe0c4, UINT_MAX, "csia"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_CSIB, 1, 0xe0c0, 0xe0c4, UINT_MAX, "csib"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_HDMI_DP0, 0, 0xe0d0, 0xe0d4, UINT_MAX, "hdmi-dp0"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_CSIC, 2, 0xe0c0, 0xe0c4, UINT_MAX, "csic"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_CSID, 3, 0xe0c0, 0xe0c4, UINT_MAX, "csid"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_CSIE, 4, 0xe0c0, 0xe0c4, UINT_MAX, "csie"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_CSIF, 5, 0xe0c0, 0xe0c4, UINT_MAX, "csif"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_UFS, 0, 0xe064, 0xe068, UINT_MAX, "ufs"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_EDP, 1, 0xe05c, 0xe060, UINT_MAX, "edp"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC1_HV, 0, 0xe054, 0xe058, 4, "sdmmc1-hv"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC3_HV, UINT_MAX, UINT_MAX, UINT_MAX, 6, "sdmmc3-hv"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_AUDIO_HV, UINT_MAX, UINT_MAX, UINT_MAX, 1, "audio-hv"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_AO_HV, UINT_MAX, UINT_MAX, UINT_MAX, 0, "ao-hv"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_CSIG, 6, 0xe0c0, 0xe0c4, UINT_MAX, "csig"),
- TEGRA_IO_PAD(TEGRA_IO_PAD_CSIH, 7, 0xe0c0, 0xe0c4, UINT_MAX, "csih"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_CSIA, 0, 0xe0c0, 0xe0c4, "csia"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_CSIB, 1, 0xe0c0, 0xe0c4, "csib"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_HDMI_DP0, 0, 0xe0d0, 0xe0d4, "hdmi-dp0"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_CSIC, 2, 0xe0c0, 0xe0c4, "csic"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_CSID, 3, 0xe0c0, 0xe0c4, "csid"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_CSIE, 4, 0xe0c0, 0xe0c4, "csie"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_CSIF, 5, 0xe0c0, 0xe0c4, "csif"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_UFS, 0, 0xe064, 0xe068, "ufs"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_EDP, 1, 0xe05c, 0xe060, "edp"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC1_HV, 0, 0xe054, 0xe058, "sdmmc1-hv"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC3_HV, UINT_MAX, UINT_MAX, UINT_MAX, "sdmmc3-hv"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_AUDIO_HV, UINT_MAX, UINT_MAX, UINT_MAX, "audio-hv"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_AO_HV, UINT_MAX, UINT_MAX, UINT_MAX, "ao-hv"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_CSIG, 6, 0xe0c0, 0xe0c4, "csig"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_CSIH, 7, 0xe0c0, 0xe0c4, "csih"),
+};
+
+static const struct tegra_io_pad_vctrl tegra234_io_pad_vctrls[] = {
+ TEGRA_IO_PAD_VCTRL(TEGRA_IO_PAD_SDMMC1_HV, PMC_IMPL_E_33V_PWR, 4),
+ TEGRA_IO_PAD_VCTRL(TEGRA_IO_PAD_SDMMC3_HV, PMC_IMPL_E_33V_PWR, 6),
+ TEGRA_IO_PAD_VCTRL(TEGRA_IO_PAD_AUDIO_HV, PMC_IMPL_E_33V_PWR, 1),
+ TEGRA_IO_PAD_VCTRL(TEGRA_IO_PAD_AO_HV, PMC_IMPL_E_33V_PWR, 0),
};
static const struct pinctrl_pin_desc tegra234_pin_descs[] = {
@@ -4400,6 +4490,14 @@ static const struct tegra_pmc_regs tegra234_pmc_regs = {
.rst_source_mask = 0xfc,
.rst_level_shift = 0x0,
.rst_level_mask = 0x3,
+ .aowake_mask_w = 0x180,
+ .aowake_status_w = 0x30c,
+ .aowake_status_r = 0x48c,
+ .aowake_tier2_routing = 0x4cc,
+ .aowake_sw_status_w = 0x49c,
+ .aowake_sw_status = 0x4a0,
+ .aowake_latch_sw = 0x498,
+ .aowake_ctrl = 0x4f4,
};
static const char * const tegra234_reset_sources[] = {
@@ -4469,10 +4567,12 @@ static const struct tegra_pmc_soc tegra234_pmc_soc = {
.has_tsense_reset = false,
.has_gpu_clamps = false,
.needs_mbist_war = false,
- .has_impl_33v_pwr = true,
+ .has_io_pad_wren = false,
.maybe_tz_only = false,
.num_io_pads = ARRAY_SIZE(tegra234_io_pads),
.io_pads = tegra234_io_pads,
+ .num_io_pad_vctrls = ARRAY_SIZE(tegra234_io_pad_vctrls),
+ .io_pad_vctrls = tegra234_io_pad_vctrls,
.num_pin_descs = ARRAY_SIZE(tegra234_pin_descs),
.pin_descs = tegra234_pin_descs,
.regs = &tegra234_pmc_regs,
@@ -4495,6 +4595,50 @@ static const struct tegra_pmc_soc tegra234_pmc_soc = {
.has_single_mmio_aperture = false,
};
+#define TEGRA264_IO_PAD_VCTRL(_id, _offset, _ena_3v3, _ena_1v8) \
+ ((struct tegra_io_pad_vctrl) { \
+ .id = (_id), \
+ .offset = (_offset), \
+ .ena_3v3 = (_ena_3v3), \
+ .ena_1v8 = (_ena_1v8), \
+ })
+
+static const struct tegra_io_pad_soc tegra264_io_pads[] = {
+ TEGRA_IO_PAD(TEGRA_IO_PAD_CSIA, 0, 0x41020, 0x41024, "csia"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_CSIB, 1, 0x41020, 0x41024, "csib"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_HDMI_DP0, 0, 0x41050, 0x41054, "hdmi-dp0"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_CSIC, 2, 0x41020, 0x41024, "csic"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_CSID, 3, 0x41020, 0x41024, "csid"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_CSIE, 4, 0x41020, 0x41024, "csie"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_CSIF, 5, 0x41020, 0x41024, "csif"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_UFS, 4, 0x41040, 0x41044, "ufs0"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_EDP, 0, 0x41028, 0x4102c, "edp"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC1, 0, 0x41090, 0x41094, "sdmmc1"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_SDMMC1_HV, UINT_MAX, UINT_MAX, UINT_MAX, "sdmmc1-hv"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_CSIG, 6, 0x41020, 0x41024, "csig"),
+ TEGRA_IO_PAD(TEGRA_IO_PAD_CSIH, 7, 0x41020, 0x41024, "csih"),
+};
+
+static const struct tegra_io_pad_vctrl tegra264_io_pad_vctrls[] = {
+ TEGRA264_IO_PAD_VCTRL(TEGRA_IO_PAD_SDMMC1_HV, PMC_IMPL_SDMMC1_HV_PADCTL_0, 0, 0x6),
+};
+
+static const struct pinctrl_pin_desc tegra264_pin_descs[] = {
+ TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_CSIA, "csia"),
+ TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_CSIB, "csib"),
+ TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_HDMI_DP0, "hdmi-dp0"),
+ TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_CSIC, "csic"),
+ TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_CSID, "csid"),
+ TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_CSIE, "csie"),
+ TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_CSIF, "csif"),
+ TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_UFS, "ufs0"),
+ TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_EDP, "edp"),
+ TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_SDMMC1, "sdmmc1"),
+ TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_SDMMC1_HV, "sdmmc1-hv"),
+ TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_CSIG, "csig"),
+ TEGRA_IO_PIN_DESC(TEGRA_IO_PAD_CSIH, "csih"),
+};
+
static const struct tegra_pmc_regs tegra264_pmc_regs = {
.scratch0 = 0x684,
.rst_status = 0x4,
@@ -4502,6 +4646,14 @@ static const struct tegra_pmc_regs tegra264_pmc_regs = {
.rst_source_mask = 0x1fc,
.rst_level_shift = 0x0,
.rst_level_mask = 0x3,
+ .aowake_mask_w = 0x200,
+ .aowake_status_w = 0x410,
+ .aowake_status_r = 0x610,
+ .aowake_tier2_routing = 0x660,
+ .aowake_sw_status_w = 0x624,
+ .aowake_sw_status = 0x628,
+ .aowake_latch_sw = 0x620,
+ .aowake_ctrl = 0x68c,
};
static const char * const tegra264_reset_sources[] = {
@@ -4595,10 +4747,26 @@ static const char * const tegra264_reset_sources[] = {
};
static const struct tegra_wake_event tegra264_wake_events[] = {
+ TEGRA_WAKE_IRQ("pmu", 0, 727),
+ TEGRA_WAKE_GPIO("power", 5, 1, TEGRA264_AON_GPIO(AA, 5)),
+ TEGRA_WAKE_IRQ("rtc", 65, 548),
+ TEGRA_WAKE_IRQ("usb3-port-0", 79, 965),
+ TEGRA_WAKE_IRQ("usb3-port-1", 80, 965),
+ TEGRA_WAKE_IRQ("usb3-port-3", 82, 965),
+ TEGRA_WAKE_IRQ("usb2-port-0", 83, 965),
+ TEGRA_WAKE_IRQ("usb2-port-1", 84, 965),
+ TEGRA_WAKE_IRQ("usb2-port-2", 85, 965),
+ TEGRA_WAKE_IRQ("usb2-port-3", 86, 965),
};
static const struct tegra_pmc_soc tegra264_pmc_soc = {
- .has_impl_33v_pwr = true,
+ .has_io_pad_wren = false,
+ .num_io_pads = ARRAY_SIZE(tegra264_io_pads),
+ .io_pads = tegra264_io_pads,
+ .num_io_pad_vctrls = ARRAY_SIZE(tegra264_io_pad_vctrls),
+ .io_pad_vctrls = tegra264_io_pad_vctrls,
+ .num_pin_descs = ARRAY_SIZE(tegra264_pin_descs),
+ .pin_descs = tegra264_pin_descs,
.regs = &tegra264_pmc_regs,
.init = tegra186_pmc_init,
.setup_irq_polarity = tegra186_pmc_setup_irq_polarity,
diff --git a/drivers/tee/optee/device.c b/drivers/tee/optee/device.c
index bae954e79fdc..f751d743a120 100644
--- a/drivers/tee/optee/device.c
+++ b/drivers/tee/optee/device.c
@@ -13,10 +13,7 @@
static int optee_ctx_match(struct tee_ioctl_version_data *ver, const void *data)
{
- if (ver->impl_id == TEE_IMPL_ID_OPTEE)
- return 1;
- else
- return 0;
+ return (ver->impl_id == TEE_IMPL_ID_OPTEE);
}
static int get_devices(struct tee_context *ctx, u32 session,
diff --git a/include/dt-bindings/arm/qcom,ids.h b/include/dt-bindings/arm/qcom,ids.h
index 8776844e0eeb..336f7bb7188a 100644
--- a/include/dt-bindings/arm/qcom,ids.h
+++ b/include/dt-bindings/arm/qcom,ids.h
@@ -245,6 +245,7 @@
#define QCOM_ID_IPQ5000 503
#define QCOM_ID_IPQ0509 504
#define QCOM_ID_IPQ0518 505
+#define QCOM_ID_SM7450 506
#define QCOM_ID_SM6375 507
#define QCOM_ID_IPQ9514 510
#define QCOM_ID_IPQ9550 511
@@ -260,10 +261,12 @@
#define QCOM_ID_SM8475 530
#define QCOM_ID_SM8475P 531
#define QCOM_ID_SA8255P 532
+#define QCOM_ID_SA8650P 533
#define QCOM_ID_SA8775P 534
#define QCOM_ID_QRU1000 539
#define QCOM_ID_SM8475_2 540
#define QCOM_ID_QDU1000 545
+#define QCOM_ID_SM7450P 547
#define QCOM_ID_X1E80100 555
#define QCOM_ID_SM8650 557
#define QCOM_ID_SM4450 568
@@ -294,6 +297,13 @@
#define QCOM_ID_QCS8275 675
#define QCOM_ID_QCS9075 676
#define QCOM_ID_QCS615 680
+#define QCOM_ID_CQ7790M 731
+#define QCOM_ID_CQ7790S 732
+#define QCOM_ID_IPQ5200 765
+#define QCOM_ID_IPQ5210 766
+#define QCOM_ID_QCF2200 767
+#define QCOM_ID_QCF3200 768
+#define QCOM_ID_QCF3210 769
/*
* The board type and revision information, used by Qualcomm bootloaders and
diff --git a/include/dt-bindings/reset/cix,sky1-s5-system-control.h b/include/dt-bindings/reset/cix,sky1-s5-system-control.h
new file mode 100644
index 000000000000..808bbcbe0c98
--- /dev/null
+++ b/include/dt-bindings/reset/cix,sky1-s5-system-control.h
@@ -0,0 +1,163 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/* Author: Jerry Zhu <jerry.zhu@cixtech.com> */
+#ifndef DT_BINDING_RESET_CIX_SKY1_S5_SYSTEM_CONTROL_H
+#define DT_BINDING_RESET_CIX_SKY1_S5_SYSTEM_CONTROL_H
+
+/* reset for csu_pm */
+#define SKY1_CSU_PM_RESET_N 0
+#define SKY1_SENSORFUSION_RESET_N 1
+#define SKY1_SENSORFUSION_NOC_RESET_N 2
+
+/* reset group0 for s0 domain modules */
+#define SKY1_DDRC_RESET_N 3
+#define SKY1_GIC_RESET_N 4
+#define SKY1_CI700_RESET_N 5
+#define SKY1_SYS_NI700_RESET_N 6
+#define SKY1_MM_NI700_RESET_N 7
+#define SKY1_PCIE_NI700_RESET_N 8
+#define SKY1_GPU_RESET_N 9
+#define SKY1_NPUTOP_RESET_N 10
+#define SKY1_NPUCORE0_RESET_N 11
+#define SKY1_NPUCORE1_RESET_N 12
+#define SKY1_NPUCORE2_RESET_N 13
+#define SKY1_VPU_RESET_N 14
+#define SKY1_ISP_SRESET_N 15
+#define SKY1_ISP_ARESET_N 16
+#define SKY1_ISP_HRESET_N 17
+#define SKY1_ISP_GDCRESET_N 18
+#define SKY1_DPU_RESET0_N 19
+#define SKY1_DPU_RESET1_N 20
+#define SKY1_DPU_RESET2_N 21
+#define SKY1_DPU_RESET3_N 22
+#define SKY1_DPU_RESET4_N 23
+#define SKY1_DP_RESET0_N 24
+#define SKY1_DP_RESET1_N 25
+#define SKY1_DP_RESET2_N 26
+#define SKY1_DP_RESET3_N 27
+#define SKY1_DP_RESET4_N 28
+#define SKY1_DP_PHY_RST_N 29
+
+/* reset group1 for s0 domain modules */
+#define SKY1_AUDIO_HIFI5_RESET_N 30
+#define SKY1_AUDIO_HIFI5_NOC_RESET_N 31
+#define SKY1_CSIDPHY_PRST0_N 32
+#define SKY1_CSIDPHY_CMNRST0_N 33
+#define SKY1_CSI0_RST_N 34
+#define SKY1_CSIDPHY_PRST1_N 35
+#define SKY1_CSIDPHY_CMNRST1_N 36
+#define SKY1_CSI1_RST_N 37
+#define SKY1_CSI2_RST_N 38
+#define SKY1_CSI3_RST_N 39
+#define SKY1_CSIBRDGE0_RST_N 40
+#define SKY1_CSIBRDGE1_RST_N 41
+#define SKY1_CSIBRDGE2_RST_N 42
+#define SKY1_CSIBRDGE3_RST_N 43
+#define SKY1_GMAC0_RST_N 44
+#define SKY1_GMAC1_RST_N 45
+#define SKY1_PCIE0_RESET_N 46
+#define SKY1_PCIE1_RESET_N 47
+#define SKY1_PCIE2_RESET_N 48
+#define SKY1_PCIE3_RESET_N 49
+#define SKY1_PCIE4_RESET_N 50
+
+/* reset group1 for usb phys */
+#define SKY1_USB_DP_PHY0_PRST_N 51
+#define SKY1_USB_DP_PHY1_PRST_N 52
+#define SKY1_USB_DP_PHY2_PRST_N 53
+#define SKY1_USB_DP_PHY3_PRST_N 54
+#define SKY1_USB_DP_PHY0_RST_N 55
+#define SKY1_USB_DP_PHY1_RST_N 56
+#define SKY1_USB_DP_PHY2_RST_N 57
+#define SKY1_USB_DP_PHY3_RST_N 58
+#define SKY1_USBPHY_SS_PST_N 59
+#define SKY1_USBPHY_SS_RST_N 60
+#define SKY1_USBPHY_HS0_PRST_N 61
+#define SKY1_USBPHY_HS1_PRST_N 62
+#define SKY1_USBPHY_HS2_PRST_N 63
+#define SKY1_USBPHY_HS3_PRST_N 64
+#define SKY1_USBPHY_HS4_PRST_N 65
+#define SKY1_USBPHY_HS5_PRST_N 66
+#define SKY1_USBPHY_HS6_PRST_N 67
+#define SKY1_USBPHY_HS7_PRST_N 68
+#define SKY1_USBPHY_HS8_PRST_N 69
+#define SKY1_USBPHY_HS9_PRST_N 70
+
+/* reset group1 for usb controllers */
+#define SKY1_USBC_SS0_PRST_N 71
+#define SKY1_USBC_SS1_PRST_N 72
+#define SKY1_USBC_SS2_PRST_N 73
+#define SKY1_USBC_SS3_PRST_N 74
+#define SKY1_USBC_SS4_PRST_N 75
+#define SKY1_USBC_SS5_PRST_N 76
+#define SKY1_USBC_SS0_RST_N 77
+#define SKY1_USBC_SS1_RST_N 78
+#define SKY1_USBC_SS2_RST_N 79
+#define SKY1_USBC_SS3_RST_N 80
+#define SKY1_USBC_SS4_RST_N 81
+#define SKY1_USBC_SS5_RST_N 82
+#define SKY1_USBC_HS0_PRST_N 83
+#define SKY1_USBC_HS1_PRST_N 84
+#define SKY1_USBC_HS2_PRST_N 85
+#define SKY1_USBC_HS3_PRST_N 86
+#define SKY1_USBC_HS0_RST_N 87
+#define SKY1_USBC_HS1_RST_N 88
+#define SKY1_USBC_HS2_RST_N 89
+#define SKY1_USBC_HS3_RST_N 90
+
+/* reset group0 for rcsu */
+#define SKY1_AUDIO_RCSU_RESET_N 91
+#define SKY1_CI700_RCSU_RESET_N 92
+#define SKY1_CSI_RCSU0_RESET_N 93
+#define SKY1_CSI_RCSU1_RESET_N 94
+#define SKY1_CSU_PM_RCSU_RESET_N 95
+#define SKY1_DDR_BROADCAST_RCSU_RESET_N 96
+#define SKY1_DDR_CTRL_RCSU_0_RESET_N 97
+#define SKY1_DDR_CTRL_RCSU_1_RESET_N 98
+#define SKY1_DDR_CTRL_RCSU_2_RESET_N 99
+#define SKY1_DDR_CTRL_RCSU_3_RESET_N 100
+#define SKY1_DDR_TZC400_RCSU_0_RESET_N 101
+#define SKY1_DDR_TZC400_RCSU_1_RESET_N 102
+#define SKY1_DDR_TZC400_RCSU_2_RESET_N 103
+#define SKY1_DDR_TZC400_RCSU_3_RESET_N 104
+#define SKY1_DP0_RCSU_RESET_N 105
+#define SKY1_DP1_RCSU_RESET_N 106
+#define SKY1_DP2_RCSU_RESET_N 107
+#define SKY1_DP3_RCSU_RESET_N 108
+#define SKY1_DP4_RCSU_RESET_N 109
+#define SKY1_DPU0_RCSU_RESET_N 110
+#define SKY1_DPU1_RCSU_RESET_N 111
+#define SKY1_DPU2_RCSU_RESET_N 112
+#define SKY1_DPU3_RCSU_RESET_N 113
+#define SKY1_DPU4_RCSU_RESET_N 114
+#define SKY1_DSU_RCSU_RESET_N 115
+#define SKY1_FCH_RCSU_RESET_N 116
+#define SKY1_GICD_RCSU_RESET_N 117
+#define SKY1_GMAC_RCSU_RESET_N 118
+#define SKY1_GPU_RCSU_RESET_N 119
+#define SKY1_ISP_RCSU0_RESET_N 120
+#define SKY1_ISP_RCSU1_RESET_N 121
+#define SKY1_NI700_MMHUB_RCSU_RESET_N 122
+
+/* reset group1 for rcsu */
+#define SKY1_NPU_RCSU_RESET_N 123
+#define SKY1_NI700_PCIE_RCSU_RESET_N 124
+#define SKY1_PCIE_X421_RCSU_RESET_N 125
+#define SKY1_PCIE_X8_RCSU_RESET_N 126
+#define SKY1_SF_RCSU_RESET_N 127
+#define SKY1_RCSU_SMMU_MMHUB_RESET_N 128
+#define SKY1_RCSU_SMMU_PCIEHUB_RESET_N 129
+#define SKY1_RCSU_SYSHUB_RESET_N 130
+#define SKY1_NI700_SMN_RCSU_RESET_N 131
+#define SKY1_NI700_SYSHUB_RCSU_RESET_N 132
+#define SKY1_RCSU_USB2_HOST0_RESET_N 133
+#define SKY1_RCSU_USB2_HOST1_RESET_N 134
+#define SKY1_RCSU_USB2_HOST2_RESET_N 135
+#define SKY1_RCSU_USB2_HOST3_RESET_N 136
+#define SKY1_RCSU_USB3_TYPEA_DRD_RESET_N 137
+#define SKY1_RCSU_USB3_TYPEC_DRD_RESET_N 138
+#define SKY1_RCSU_USB3_TYPEC_HOST0_RESET_N 139
+#define SKY1_RCSU_USB3_TYPEC_HOST1_RESET_N 140
+#define SKY1_RCSU_USB3_TYPEC_HOST2_RESET_N 141
+#define SKY1_VPU_RCSU_RESET_N 142
+
+#endif
diff --git a/include/dt-bindings/reset/cix,sky1-system-control.h b/include/dt-bindings/reset/cix,sky1-system-control.h
new file mode 100644
index 000000000000..7a16fc4ef3b5
--- /dev/null
+++ b/include/dt-bindings/reset/cix,sky1-system-control.h
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/* Author: Jerry Zhu <jerry.zhu@cixtech.com> */
+#ifndef DT_BINDING_RESET_CIX_SKY1_SYSTEM_CONTROL_H
+#define DT_BINDING_RESET_CIX_SKY1_SYSTEM_CONTROL_H
+
+/* func reset for sky1 fch */
+#define SW_I3C0_RST_FUNC_G_N 0
+#define SW_I3C0_RST_FUNC_I_N 1
+#define SW_I3C1_RST_FUNC_G_N 2
+#define SW_I3C1_RST_FUNC_I_N 3
+#define SW_UART0_RST_FUNC_N 4
+#define SW_UART1_RST_FUNC_N 5
+#define SW_UART2_RST_FUNC_N 6
+#define SW_UART3_RST_FUNC_N 7
+#define SW_TIMER_RST_FUNC_N 8
+
+/* apb reset for sky1 fch */
+#define SW_I3C0_RST_APB_N 9
+#define SW_I3C1_RST_APB_N 10
+#define SW_DMA_RST_AXI_N 11
+#define SW_UART0_RST_APB_N 12
+#define SW_UART1_RST_APB_N 13
+#define SW_UART2_RST_APB_N 14
+#define SW_UART3_RST_APB_N 15
+#define SW_SPI0_RST_APB_N 16
+#define SW_SPI1_RST_APB_N 17
+#define SW_I2C0_RST_APB_N 18
+#define SW_I2C1_RST_APB_N 19
+#define SW_I2C2_RST_APB_N 20
+#define SW_I2C3_RST_APB_N 21
+#define SW_I2C4_RST_APB_N 22
+#define SW_I2C5_RST_APB_N 23
+#define SW_I2C6_RST_APB_N 24
+#define SW_I2C7_RST_APB_N 25
+#define SW_GPIO_RST_APB_N 26
+
+/* fch rst for xspi */
+#define SW_XSPI_REG_RST_N 27
+#define SW_XSPI_SYS_RST_N 28
+
+#endif
diff --git a/drivers/bus/stm32_firewall.h b/include/linux/bus/stm32_firewall.h
index e5fac85fe346..e5fac85fe346 100644
--- a/drivers/bus/stm32_firewall.h
+++ b/include/linux/bus/stm32_firewall.h
diff --git a/include/linux/bus/stm32_firewall_device.h b/include/linux/bus/stm32_firewall_device.h
index eaa7a3f54450..6c878f3ca86f 100644
--- a/include/linux/bus/stm32_firewall_device.h
+++ b/include/linux/bus/stm32_firewall_device.h
@@ -112,6 +112,25 @@ int stm32_firewall_grant_access_by_id(struct stm32_firewall *firewall, u32 subsy
*/
void stm32_firewall_release_access_by_id(struct stm32_firewall *firewall, u32 subsystem_id);
+/**
+ * stm32_firewall_get_grant_all_access - Allocate and get all the firewall(s) associated to given
+ * device. Then, try to grant access rights for each element.
+ * This function is basically a helper function that wraps
+ * both stm32_firewall_get_firewall() and
+ * stm32_firewall_grant_access() on all firewall references of
+ * a device along with the allocation of the array.
+ * Realease access using stm32_firewall_release_access* APIs
+ * when done.
+ *
+ * @dev: Device performing the checks
+ * @firewall: Pointer to the array of firewall references to be allocated
+ * @nb_firewall: Number of allocated elements in @firewall
+ *
+ * Returns 0 on success, or appropriate errno code if error occurred.
+ */
+int stm32_firewall_get_grant_all_access(struct device *dev, struct stm32_firewall **firewall,
+ int *nb_firewall);
+
#else /* CONFIG_STM32_FIREWALL */
static inline int stm32_firewall_get_firewall(struct device_node *np,
@@ -141,5 +160,12 @@ static inline void stm32_firewall_release_access_by_id(struct stm32_firewall *fi
{
}
+static inline int stm32_firewall_get_grant_all_access(struct device *dev,
+ struct stm32_firewall **firewall,
+ int *nb_firewall)
+{
+ return -ENODEV;
+}
+
#endif /* CONFIG_STM32_FIREWALL */
#endif /* STM32_FIREWALL_DEVICE_H */
diff --git a/include/linux/firmware/samsung/exynos-acpm-protocol.h b/include/linux/firmware/samsung/exynos-acpm-protocol.h
index 2091da965a5a..13f17dc4443b 100644
--- a/include/linux/firmware/samsung/exynos-acpm-protocol.h
+++ b/include/linux/firmware/samsung/exynos-acpm-protocol.h
@@ -14,30 +14,24 @@ struct acpm_handle;
struct device_node;
struct acpm_dvfs_ops {
- int (*set_rate)(const struct acpm_handle *handle,
- unsigned int acpm_chan_id, unsigned int clk_id,
- unsigned long rate);
- unsigned long (*get_rate)(const struct acpm_handle *handle,
+ int (*set_rate)(struct acpm_handle *handle, unsigned int acpm_chan_id,
+ unsigned int clk_id, unsigned long rate);
+ unsigned long (*get_rate)(struct acpm_handle *handle,
unsigned int acpm_chan_id,
unsigned int clk_id);
};
struct acpm_pmic_ops {
- int (*read_reg)(const struct acpm_handle *handle,
- unsigned int acpm_chan_id, u8 type, u8 reg, u8 chan,
- u8 *buf);
- int (*bulk_read)(const struct acpm_handle *handle,
- unsigned int acpm_chan_id, u8 type, u8 reg, u8 chan,
- u8 count, u8 *buf);
- int (*write_reg)(const struct acpm_handle *handle,
- unsigned int acpm_chan_id, u8 type, u8 reg, u8 chan,
- u8 value);
- int (*bulk_write)(const struct acpm_handle *handle,
- unsigned int acpm_chan_id, u8 type, u8 reg, u8 chan,
- u8 count, const u8 *buf);
- int (*update_reg)(const struct acpm_handle *handle,
- unsigned int acpm_chan_id, u8 type, u8 reg, u8 chan,
- u8 value, u8 mask);
+ int (*read_reg)(struct acpm_handle *handle, unsigned int acpm_chan_id,
+ u8 type, u8 reg, u8 chan, u8 *buf);
+ int (*bulk_read)(struct acpm_handle *handle, unsigned int acpm_chan_id,
+ u8 type, u8 reg, u8 chan, u8 count, u8 *buf);
+ int (*write_reg)(struct acpm_handle *handle, unsigned int acpm_chan_id,
+ u8 type, u8 reg, u8 chan, u8 value);
+ int (*bulk_write)(struct acpm_handle *handle, unsigned int acpm_chan_id,
+ u8 type, u8 reg, u8 chan, u8 count, const u8 *buf);
+ int (*update_reg)(struct acpm_handle *handle, unsigned int acpm_chan_id,
+ u8 type, u8 reg, u8 chan, u8 value, u8 mask);
};
struct acpm_ops {
@@ -56,12 +50,12 @@ struct acpm_handle {
struct device;
#if IS_ENABLED(CONFIG_EXYNOS_ACPM_PROTOCOL)
-const struct acpm_handle *devm_acpm_get_by_node(struct device *dev,
- struct device_node *np);
+struct acpm_handle *devm_acpm_get_by_node(struct device *dev,
+ struct device_node *np);
#else
-static inline const struct acpm_handle *devm_acpm_get_by_node(struct device *dev,
- struct device_node *np)
+static inline struct acpm_handle *devm_acpm_get_by_node(struct device *dev,
+ struct device_node *np)
{
return NULL;
}
diff --git a/include/linux/reset-controller.h b/include/linux/reset-controller.h
index 46514cb1b9e0..52a5a4e81f18 100644
--- a/include/linux/reset-controller.h
+++ b/include/linux/reset-controller.h
@@ -3,7 +3,10 @@
#define _LINUX_RESET_CONTROLLER_H_
#include <linux/list.h>
+#include <linux/mutex.h>
+struct fwnode_handle;
+struct fwnode_reference_args;
struct reset_controller_dev;
/**
@@ -35,14 +38,16 @@ struct of_phandle_args;
* @reset_control_head: head of internal list of requested reset controls
* @dev: corresponding driver model device struct
* @of_node: corresponding device tree node as phandle target
- * @of_args: for reset-gpios controllers: corresponding phandle args with
- * of_node and GPIO number complementing of_node; either this or
- * of_node should be present
* @of_reset_n_cells: number of cells in reset line specifiers
* @of_xlate: translation function to translate from specifier as found in the
- * device tree to id as given to the reset control ops, defaults
- * to :c:func:`of_reset_simple_xlate`.
+ * device tree to id as given to the reset control ops
+ * @fwnode: firmware node associated with this device
+ * @fwnode_reset_n_cells: number of cells in reset line specifiers
+ * @fwnode_xlate: translation function to translate from firmware specifier to
+ * id as given to the reset control ops, defaults to
+ * :c:func:`fwnode_reset_simple_xlate`
* @nr_resets: number of reset controls in this reset controller device
+ * @lock: protects the reset control list from concurrent access
*/
struct reset_controller_dev {
const struct reset_control_ops *ops;
@@ -51,11 +56,15 @@ struct reset_controller_dev {
struct list_head reset_control_head;
struct device *dev;
struct device_node *of_node;
- const struct of_phandle_args *of_args;
int of_reset_n_cells;
int (*of_xlate)(struct reset_controller_dev *rcdev,
const struct of_phandle_args *reset_spec);
+ struct fwnode_handle *fwnode;
+ int fwnode_reset_n_cells;
+ int (*fwnode_xlate)(struct reset_controller_dev *rcdev,
+ const struct fwnode_reference_args *reset_spec);
unsigned int nr_resets;
+ struct mutex lock;
};
#if IS_ENABLED(CONFIG_RESET_CONTROLLER)
diff --git a/include/linux/reset.h b/include/linux/reset.h
index 44f9e3415f92..9c391cf0c822 100644
--- a/include/linux/reset.h
+++ b/include/linux/reset.h
@@ -5,10 +5,12 @@
#include <linux/bits.h>
#include <linux/err.h>
#include <linux/errno.h>
+#include <linux/of.h>
#include <linux/types.h>
struct device;
struct device_node;
+struct fwnode_handle;
struct reset_control;
/**
@@ -84,7 +86,7 @@ int reset_control_bulk_deassert(int num_rstcs, struct reset_control_bulk_data *r
int reset_control_bulk_acquire(int num_rstcs, struct reset_control_bulk_data *rstcs);
void reset_control_bulk_release(int num_rstcs, struct reset_control_bulk_data *rstcs);
-struct reset_control *__of_reset_control_get(struct device_node *node,
+struct reset_control *__fwnode_reset_control_get(struct fwnode_handle *fwnode,
const char *id, int index, enum reset_control_flags flags);
struct reset_control *__reset_control_get(struct device *dev, const char *id,
int index, enum reset_control_flags flags);
@@ -103,7 +105,8 @@ int __devm_reset_control_bulk_get(struct device *dev, int num_rstcs,
struct reset_control *devm_reset_control_array_get(struct device *dev,
enum reset_control_flags flags);
-struct reset_control *of_reset_control_array_get(struct device_node *np, enum reset_control_flags);
+struct reset_control *fwnode_reset_control_array_get(struct fwnode_handle *fwnode,
+ enum reset_control_flags);
int reset_control_get_count(struct device *dev);
@@ -152,8 +155,8 @@ static inline int __device_reset(struct device *dev, bool optional)
return optional ? 0 : -ENOTSUPP;
}
-static inline struct reset_control *__of_reset_control_get(
- struct device_node *node,
+static inline struct reset_control *__fwnode_reset_control_get(
+ struct fwnode_handle *fwnode,
const char *id, int index, enum reset_control_flags flags)
{
bool optional = flags & RESET_CONTROL_FLAGS_BIT_OPTIONAL;
@@ -242,7 +245,7 @@ devm_reset_control_array_get(struct device *dev, enum reset_control_flags flags)
}
static inline struct reset_control *
-of_reset_control_array_get(struct device_node *np, enum reset_control_flags flags)
+fwnode_reset_control_array_get(struct fwnode_handle *fwnode, enum reset_control_flags flags)
{
bool optional = flags & RESET_CONTROL_FLAGS_BIT_OPTIONAL;
@@ -500,7 +503,8 @@ reset_control_bulk_get_optional_shared(struct device *dev, int num_rstcs,
static inline struct reset_control *of_reset_control_get_exclusive(
struct device_node *node, const char *id)
{
- return __of_reset_control_get(node, id, 0, RESET_CONTROL_EXCLUSIVE);
+ return __fwnode_reset_control_get(of_fwnode_handle(node), id, 0,
+ RESET_CONTROL_EXCLUSIVE);
}
/**
@@ -520,7 +524,8 @@ static inline struct reset_control *of_reset_control_get_exclusive(
static inline struct reset_control *of_reset_control_get_optional_exclusive(
struct device_node *node, const char *id)
{
- return __of_reset_control_get(node, id, 0, RESET_CONTROL_OPTIONAL_EXCLUSIVE);
+ return __fwnode_reset_control_get(of_fwnode_handle(node), id, 0,
+ RESET_CONTROL_OPTIONAL_EXCLUSIVE);
}
/**
@@ -545,7 +550,8 @@ static inline struct reset_control *of_reset_control_get_optional_exclusive(
static inline struct reset_control *of_reset_control_get_shared(
struct device_node *node, const char *id)
{
- return __of_reset_control_get(node, id, 0, RESET_CONTROL_SHARED);
+ return __fwnode_reset_control_get(of_fwnode_handle(node), id, 0,
+ RESET_CONTROL_SHARED);
}
/**
@@ -562,7 +568,8 @@ static inline struct reset_control *of_reset_control_get_shared(
static inline struct reset_control *of_reset_control_get_exclusive_by_index(
struct device_node *node, int index)
{
- return __of_reset_control_get(node, NULL, index, RESET_CONTROL_EXCLUSIVE);
+ return __fwnode_reset_control_get(of_fwnode_handle(node), NULL, index,
+ RESET_CONTROL_EXCLUSIVE);
}
/**
@@ -590,7 +597,8 @@ static inline struct reset_control *of_reset_control_get_exclusive_by_index(
static inline struct reset_control *of_reset_control_get_shared_by_index(
struct device_node *node, int index)
{
- return __of_reset_control_get(node, NULL, index, RESET_CONTROL_SHARED);
+ return __fwnode_reset_control_get(of_fwnode_handle(node), NULL, index,
+ RESET_CONTROL_SHARED);
}
/**
@@ -1032,30 +1040,35 @@ devm_reset_control_array_get_optional_shared(struct device *dev)
static inline struct reset_control *
of_reset_control_array_get_exclusive(struct device_node *node)
{
- return of_reset_control_array_get(node, RESET_CONTROL_EXCLUSIVE);
+ return fwnode_reset_control_array_get(of_fwnode_handle(node),
+ RESET_CONTROL_EXCLUSIVE);
}
static inline struct reset_control *
of_reset_control_array_get_exclusive_released(struct device_node *node)
{
- return of_reset_control_array_get(node, RESET_CONTROL_EXCLUSIVE_RELEASED);
+ return fwnode_reset_control_array_get(of_fwnode_handle(node),
+ RESET_CONTROL_EXCLUSIVE_RELEASED);
}
static inline struct reset_control *
of_reset_control_array_get_shared(struct device_node *node)
{
- return of_reset_control_array_get(node, RESET_CONTROL_SHARED);
+ return fwnode_reset_control_array_get(of_fwnode_handle(node),
+ RESET_CONTROL_SHARED);
}
static inline struct reset_control *
of_reset_control_array_get_optional_exclusive(struct device_node *node)
{
- return of_reset_control_array_get(node, RESET_CONTROL_OPTIONAL_EXCLUSIVE);
+ return fwnode_reset_control_array_get(of_fwnode_handle(node),
+ RESET_CONTROL_OPTIONAL_EXCLUSIVE);
}
static inline struct reset_control *
of_reset_control_array_get_optional_shared(struct device_node *node)
{
- return of_reset_control_array_get(node, RESET_CONTROL_OPTIONAL_SHARED);
+ return fwnode_reset_control_array_get(of_fwnode_handle(node),
+ RESET_CONTROL_OPTIONAL_SHARED);
}
#endif
diff --git a/include/linux/soc/qcom/llcc-qcom.h b/include/linux/soc/qcom/llcc-qcom.h
index 8243ab3a12a8..227125d84318 100644
--- a/include/linux/soc/qcom/llcc-qcom.h
+++ b/include/linux/soc/qcom/llcc-qcom.h
@@ -91,10 +91,12 @@
* struct llcc_slice_desc - Cache slice descriptor
* @slice_id: llcc slice id
* @slice_size: Size allocated for the llcc slice
+ * @refcount: Atomic counter to track activate/deactivate calls
*/
struct llcc_slice_desc {
u32 slice_id;
size_t slice_size;
+ refcount_t refcount;
};
/**
@@ -152,11 +154,10 @@ struct llcc_edac_reg_offset {
* @edac_reg_offset: Offset of the LLCC EDAC registers
* @lock: mutex associated with each slice
* @cfg_size: size of the config data table
- * @max_slices: max slices as read from device tree
* @num_banks: Number of llcc banks
- * @bitmap: Bit map to track the active slice ids
* @ecc_irq: interrupt for llcc cache error detection and reporting
* @ecc_irq_configured: 'True' if firmware has already configured the irq propagation
+ * @desc: Array pointer of pre-allocated LLCC slice descriptors
* @version: Indicates the LLCC version
*/
struct llcc_drv_data {
@@ -167,12 +168,11 @@ struct llcc_drv_data {
const struct llcc_edac_reg_offset *edac_reg_offset;
struct mutex lock;
u32 cfg_size;
- u32 max_slices;
u32 num_banks;
- unsigned long *bitmap;
int ecc_irq;
bool ecc_irq_configured;
u32 version;
+ struct llcc_slice_desc *desc;
};
#if IS_ENABLED(CONFIG_QCOM_LLCC)
diff --git a/include/linux/soc/qcom/qmi.h b/include/linux/soc/qcom/qmi.h
index 291cdc7ef49c..b9dcb437a0be 100644
--- a/include/linux/soc/qcom/qmi.h
+++ b/include/linux/soc/qcom/qmi.h
@@ -92,6 +92,18 @@ struct qmi_elem_info {
#define QMI_ERR_INCOMPATIBLE_STATE_V01 90
#define QMI_ERR_NOT_SUPPORTED_V01 94
+/*
+ * Enumerate the IDs of the QMI services
+ */
+#define QMI_SERVICE_ID_TEST 0x0f /* 15 */
+#define QMI_SERVICE_ID_SSCTL 0x2b /* 43 */
+#define QMI_SERVICE_ID_IPA 0x31 /* 49 */
+#define QMI_SERVICE_ID_SERVREG_LOC 0x40 /* 64 */
+#define QMI_SERVICE_ID_SERVREG_NOTIF 0x42 /* 66 */
+#define QMI_SERVICE_ID_WLFW 0x45 /* 69 */
+#define QMI_SERVICE_ID_SLIMBUS 0x301 /* 769 */
+#define QMI_SERVICE_ID_USB_AUDIO_STREAM 0x41d /* 1053 */
+
/**
* struct qmi_response_type_v01 - common response header (decoded)
* @result: result of the transaction
diff --git a/include/linux/soc/qcom/ubwc.h b/include/linux/soc/qcom/ubwc.h
index f052e241736c..f5d0e2341261 100644
--- a/include/linux/soc/qcom/ubwc.h
+++ b/include/linux/soc/qcom/ubwc.h
@@ -74,4 +74,29 @@ static inline bool qcom_ubwc_get_ubwc_mode(const struct qcom_ubwc_cfg_data *cfg)
return ret;
}
+/*
+ * This is the best guess, based on the MDSS driver, which worked so far.
+ */
+static inline bool qcom_ubwc_min_acc_length_64b(const struct qcom_ubwc_cfg_data *cfg)
+{
+ return cfg->ubwc_enc_version == UBWC_1_0 &&
+ (cfg->ubwc_dec_version == UBWC_2_0 ||
+ cfg->ubwc_dec_version == UBWC_3_0);
+}
+
+static inline bool qcom_ubwc_macrotile_mode(const struct qcom_ubwc_cfg_data *cfg)
+{
+ return cfg->macrotile_mode;
+}
+
+static inline bool qcom_ubwc_bank_spread(const struct qcom_ubwc_cfg_data *cfg)
+{
+ return cfg->ubwc_bank_spread;
+}
+
+static inline u32 qcom_ubwc_swizzle(const struct qcom_ubwc_cfg_data *cfg)
+{
+ return cfg->ubwc_swizzle;
+}
+
#endif /* __QCOM_UBWC_H__ */
diff --git a/include/linux/tee_core.h b/include/linux/tee_core.h
index ee5f0bd41f43..f993d5118edd 100644
--- a/include/linux/tee_core.h
+++ b/include/linux/tee_core.h
@@ -50,7 +50,7 @@ enum tee_dma_heap_id {
* @dev: embedded basic device structure
* @cdev: embedded cdev
* @num_users: number of active users of this device
- * @c_no_user: completion used when unregistering the device
+ * @c_no_users: completion used when unregistering the device
* @mutex: mutex protecting @num_users and @idr
* @idr: register of user space shared memory objects allocated or
* registered on this device
@@ -132,6 +132,7 @@ struct tee_driver_ops {
/* Size for TEE revision string buffer used by get_tee_revision(). */
#define TEE_REVISION_STR_SIZE 128
+#define TEE_DESC_PRIVILEGED 0x1
/**
* struct tee_desc - Describes the TEE driver to the subsystem
* @name: name of driver
@@ -139,7 +140,6 @@ struct tee_driver_ops {
* @owner: module providing the driver
* @flags: Extra properties of driver, defined by TEE_DESC_* below
*/
-#define TEE_DESC_PRIVILEGED 0x1
struct tee_desc {
const char *name;
const struct tee_driver_ops *ops;
@@ -187,7 +187,7 @@ struct tee_protmem_pool_ops {
* Allocates a new struct tee_device instance. The device is
* removed by tee_device_unregister().
*
- * @returns a pointer to a 'struct tee_device' or an ERR_PTR on failure
+ * @returns: a pointer to a 'struct tee_device' or an ERR_PTR on failure
*/
struct tee_device *tee_device_alloc(const struct tee_desc *teedesc,
struct device *dev,
@@ -201,7 +201,7 @@ struct tee_device *tee_device_alloc(const struct tee_desc *teedesc,
* tee_device_unregister() need to be called to remove the @teedev if
* this function fails.
*
- * @returns < 0 on failure
+ * @returns: < 0 on failure
*/
int tee_device_register(struct tee_device *teedev);
@@ -254,14 +254,14 @@ void tee_device_set_dev_groups(struct tee_device *teedev,
* tee_session_calc_client_uuid() - Calculates client UUID for session
* @uuid: Resulting UUID
* @connection_method: Connection method for session (TEE_IOCTL_LOGIN_*)
- * @connectuon_data: Connection data for opening session
+ * @connection_data: Connection data for opening session
*
* Based on connection method calculates UUIDv5 based client UUID.
*
* For group based logins verifies that calling process has specified
* credentials.
*
- * @return < 0 on failure
+ * @returns: < 0 on failure
*/
int tee_session_calc_client_uuid(uuid_t *uuid, u32 connection_method,
const u8 connection_data[TEE_IOCTL_UUID_LEN]);
@@ -295,7 +295,7 @@ struct tee_shm_pool_ops {
* @paddr: Physical address of start of pool
* @size: Size in bytes of the pool
*
- * @returns pointer to a 'struct tee_shm_pool' or an ERR_PTR on failure.
+ * @returns: pointer to a 'struct tee_shm_pool' or an ERR_PTR on failure.
*/
struct tee_shm_pool *tee_shm_pool_alloc_res_mem(unsigned long vaddr,
phys_addr_t paddr, size_t size,
@@ -318,14 +318,16 @@ static inline void tee_shm_pool_free(struct tee_shm_pool *pool)
* @paddr: Physical address of start of pool
* @size: Size in bytes of the pool
*
- * @returns pointer to a 'struct tee_protmem_pool' or an ERR_PTR on failure.
+ * @returns: pointer to a 'struct tee_protmem_pool' or an ERR_PTR on failure.
*/
struct tee_protmem_pool *tee_protmem_static_pool_alloc(phys_addr_t paddr,
size_t size);
/**
* tee_get_drvdata() - Return driver_data pointer
- * @returns the driver_data pointer supplied to tee_register().
+ * @teedev: Pointer to the tee_device
+ *
+ * @returns: the driver_data pointer supplied to tee_register().
*/
void *tee_get_drvdata(struct tee_device *teedev);
@@ -334,7 +336,7 @@ void *tee_get_drvdata(struct tee_device *teedev);
* TEE driver
* @ctx: The TEE context for shared memory allocation
* @size: Shared memory allocation size
- * @returns a pointer to 'struct tee_shm' on success or an ERR_PTR on failure
+ * @returns: a pointer to 'struct tee_shm' on success or an ERR_PTR on failure
*/
struct tee_shm *tee_shm_alloc_priv_buf(struct tee_context *ctx, size_t size);
@@ -354,7 +356,7 @@ void tee_dyn_shm_free_helper(struct tee_shm *shm,
/**
* tee_shm_is_dynamic() - Check if shared memory object is of the dynamic kind
* @shm: Shared memory handle
- * @returns true if object is dynamic shared memory
+ * @returns: true if object is dynamic shared memory
*/
static inline bool tee_shm_is_dynamic(struct tee_shm *shm)
{
@@ -370,7 +372,7 @@ void tee_shm_put(struct tee_shm *shm);
/**
* tee_shm_get_id() - Get id of a shared memory object
* @shm: Shared memory handle
- * @returns id
+ * @returns: id
*/
static inline int tee_shm_get_id(struct tee_shm *shm)
{
@@ -382,7 +384,7 @@ static inline int tee_shm_get_id(struct tee_shm *shm)
* count
* @ctx: Context owning the shared memory
* @id: Id of shared memory object
- * @returns a pointer to 'struct tee_shm' on success or an ERR_PTR on failure
+ * @returns: a pointer to 'struct tee_shm' on success or an ERR_PTR on failure
*/
struct tee_shm *tee_shm_get_from_id(struct tee_context *ctx, int id);
@@ -402,7 +404,7 @@ static inline bool tee_param_is_memref(struct tee_param *param)
* teedev_open() - Open a struct tee_device
* @teedev: Device to open
*
- * @return a pointer to struct tee_context on success or an ERR_PTR on failure.
+ * @returns: pointer to struct tee_context on success or an ERR_PTR on failure.
*/
struct tee_context *teedev_open(struct tee_device *teedev);
diff --git a/include/soc/tegra/bpmp-abi.h b/include/soc/tegra/bpmp-abi.h
index dc0789c20333..5c64b3e02211 100644
--- a/include/soc/tegra/bpmp-abi.h
+++ b/include/soc/tegra/bpmp-abi.h
@@ -1,6 +1,6 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
/*
- * Copyright (c) 2014-2022, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2014-2025, NVIDIA CORPORATION. All rights reserved.
*/
#ifndef ABI_BPMP_ABI_H
@@ -74,6 +74,7 @@
/**
* @ingroup MRQ_Format
+ *
* Request an answer from the peer.
* This should be set in mrq_request::flags for all requests targetted
* at BPMP. For requests originating in BPMP, this flag is optional except
@@ -85,6 +86,7 @@
/**
* @ingroup MRQ_Format
+ *
* Ring the sender's doorbell when responding. This should be set unless
* the sender wants to poll the underlying communications layer directly.
*
@@ -94,7 +96,9 @@
/**
* @ingroup MRQ_Format
- * CRC present
+ *
+ * This is set in mrq_request::flags for requests that have CRC present and
+ * correspondingly in mrq_response::flags for responses that have CRC present.
*/
#define BPMP_MAIL_CRC_PRESENT (1U << 2U)
@@ -127,91 +131,319 @@ struct mrq_request {
* crc16, xid and length fields are present when set.
* Some platform configurations, especially when targeted to applications requiring
* functional safety, mandate this option being set or otherwise will respond with
- * -BPMP_EBADMSG and ignore the request.
+ * -#BPMP_EBADMSG and ignore the request.
*
* **xid** is a transaction ID.
*
* Only used when #BPMP_MAIL_CRC_PRESENT is set.
*
* **payload_length** of the message expressed in bytes without the size of this header.
- * See table below for minimum accepted payload lengths for each MRQ.
- * Note: For DMCE communication, this field expresses the length as a multiple of 4 bytes
- * rather than bytes.
+ * See tables below for minimum accepted payload lengths for each MRQ.
*
* Only used when #BPMP_MAIL_CRC_PRESENT is set.
*
- * | MRQ | CMD | minimum payload length
- * | -------------------- | ------------------------------------ | ------------------------------------------ |
- * | MRQ_PING | | 4 |
- * | MRQ_THREADED_PING | | 4 |
- * | MRQ_RESET | any | 8 |
- * | MRQ_I2C | | 12 + cmd_i2c_xfer_request.data_size |
- * | MRQ_CLK | CMD_CLK_GET_RATE | 4 |
- * | MRQ_CLK | CMD_CLK_SET_RATE | 16 |
- * | MRQ_CLK | CMD_CLK_ROUND_RATE | 16 |
- * | MRQ_CLK | CMD_CLK_GET_PARENT | 4 |
- * | MRQ_CLK | CMD_CLK_SET_PARENT | 8 |
- * | MRQ_CLK | CMD_CLK_ENABLE | 4 |
- * | MRQ_CLK | CMD_CLK_DISABLE | 4 |
- * | MRQ_CLK | CMD_CLK_IS_ENABLED | 4 |
- * | MRQ_CLK | CMD_CLK_GET_ALL_INFO | 4 |
- * | MRQ_CLK | CMD_CLK_GET_MAX_CLK_ID | 4 |
- * | MRQ_CLK | CMD_CLK_GET_FMAX_AT_VMIN | 4 |
- * | MRQ_QUERY_ABI | | 4 |
- * | MRQ_PG | CMD_PG_QUERY_ABI | 12 |
- * | MRQ_PG | CMD_PG_SET_STATE | 12 |
- * | MRQ_PG | CMD_PG_GET_STATE | 8 |
- * | MRQ_PG | CMD_PG_GET_NAME | 8 |
- * | MRQ_PG | CMD_PG_GET_MAX_ID | 8 |
- * | MRQ_THERMAL | CMD_THERMAL_QUERY_ABI | 8 |
- * | MRQ_THERMAL | CMD_THERMAL_GET_TEMP | 8 |
- * | MRQ_THERMAL | CMD_THERMAL_SET_TRIP | 20 |
- * | MRQ_THERMAL | CMD_THERMAL_GET_NUM_ZONES | 4 |
- * | MRQ_THERMAL | CMD_THERMAL_GET_THERMTRIP | 8 |
- * | MRQ_CPU_VHINT | | 8 |
- * | MRQ_ABI_RATCHET | | 2 |
- * | MRQ_EMC_DVFS_LATENCY | | 8 |
- * | MRQ_EMC_DVFS_EMCHUB | | 8 |
- * | MRQ_EMC_DISP_RFL | | 4 |
- * | MRQ_BWMGR | CMD_BWMGR_QUERY_ABI | 8 |
- * | MRQ_BWMGR | CMD_BWMGR_CALC_RATE | 8 + 8 * bwmgr_rate_req.num_iso_clients |
- * | MRQ_ISO_CLIENT | CMD_ISO_CLIENT_QUERY_ABI | 8 |
- * | MRQ_ISO_CLIENT | CMD_ISO_CLIENT_CALCULATE_LA | 16 |
- * | MRQ_ISO_CLIENT | CMD_ISO_CLIENT_SET_LA | 16 |
- * | MRQ_ISO_CLIENT | CMD_ISO_CLIENT_GET_MAX_BW | 8 |
- * | MRQ_CPU_NDIV_LIMITS | | 4 |
- * | MRQ_CPU_AUTO_CC3 | | 4 |
- * | MRQ_RINGBUF_CONSOLE | CMD_RINGBUF_CONSOLE_QUERY_ABI | 8 |
- * | MRQ_RINGBUF_CONSOLE | CMD_RINGBUF_CONSOLE_READ | 5 |
- * | MRQ_RINGBUF_CONSOLE | CMD_RINGBUF_CONSOLE_WRITE | 5 + cmd_ringbuf_console_write_req.len |
- * | MRQ_RINGBUF_CONSOLE | CMD_RINGBUF_CONSOLE_GET_FIFO | 4 |
- * | MRQ_STRAP | STRAP_SET | 12 |
- * | MRQ_UPHY | CMD_UPHY_PCIE_LANE_MARGIN_CONTROL | 24 |
- * | MRQ_UPHY | CMD_UPHY_PCIE_LANE_MARGIN_STATUS | 4 |
- * | MRQ_UPHY | CMD_UPHY_PCIE_EP_CONTROLLER_PLL_INIT | 5 |
- * | MRQ_UPHY | CMD_UPHY_PCIE_CONTROLLER_STATE | 6 |
- * | MRQ_UPHY | CMD_UPHY_PCIE_EP_CONTROLLER_PLL_OFF | 5 |
- * | MRQ_FMON | CMD_FMON_GEAR_CLAMP | 16 |
- * | MRQ_FMON | CMD_FMON_GEAR_FREE | 4 |
- * | MRQ_FMON | CMD_FMON_GEAR_GET | 4 |
- * | MRQ_FMON | CMD_FMON_FAULT_STS_GET | 8 |
- * | MRQ_EC | CMD_EC_STATUS_EX_GET | 12 |
- * | MRQ_QUERY_FW_TAG | | 0 |
- * | MRQ_DEBUG | CMD_DEBUG_OPEN_RO | 4 + length of cmd_debug_fopen_request.name |
- * | MRQ_DEBUG | CMD_DEBUG_OPEN_WO | 4 + length of cmd_debug_fopen_request.name |
- * | MRQ_DEBUG | CMD_DEBUG_READ | 8 |
- * | MRQ_DEBUG | CMD_DEBUG_WRITE | 12 + cmd_debug_fwrite_request.datalen |
- * | MRQ_DEBUG | CMD_DEBUG_CLOSE | 8 |
- * | MRQ_TELEMETRY | | 8 |
- * | MRQ_PWR_LIMIT | CMD_PWR_LIMIT_QUERY_ABI | 8 |
- * | MRQ_PWR_LIMIT | CMD_PWR_LIMIT_SET | 20 |
- * | MRQ_PWR_LIMIT | CMD_PWR_LIMIT_GET | 16 |
- * | MRQ_PWR_LIMIT | CMD_PWR_LIMIT_CURR_CAP | 8 |
- * | MRQ_GEARS | | 0 |
- * | MRQ_BWMGR_INT | CMD_BWMGR_INT_QUERY_ABI | 8 |
- * | MRQ_BWMGR_INT | CMD_BWMGR_INT_CALC_AND_SET | 16 |
- * | MRQ_BWMGR_INT | CMD_BWMGR_INT_CAP_SET | 8 |
- * | MRQ_OC_STATUS | | 0 |
+ * | MRQ | Sub-command | Minimum payload length
+ * | --------------------- | ------------------------------------ | ------------------------------------------------------- |
+ * | #MRQ_PING | - | 4 |
+ * | #MRQ_THREADED_PING | - | 4 |
+ * | #MRQ_RESET | any | 8 |
+ * | #MRQ_I2C | - | 12 + cmd_i2c_xfer_request.data_size |
+ * | #MRQ_CLK | #CMD_CLK_GET_RATE | 4 |
+ * | #MRQ_CLK | #CMD_CLK_SET_RATE | 16 |
+ * | #MRQ_CLK | #CMD_CLK_ROUND_RATE | 16 |
+ * | #MRQ_CLK | #CMD_CLK_GET_PARENT | 4 |
+ * | #MRQ_CLK | #CMD_CLK_SET_PARENT | 8 |
+ * | #MRQ_CLK | #CMD_CLK_ENABLE | 4 |
+ * | #MRQ_CLK | #CMD_CLK_DISABLE | 4 |
+ * | #MRQ_CLK | #CMD_CLK_IS_ENABLED | 4 |
+ * | #MRQ_CLK | #CMD_CLK_GET_ALL_INFO | 4 |
+ * | #MRQ_CLK | #CMD_CLK_GET_MAX_CLK_ID | 4 |
+ * | #MRQ_CLK | #CMD_CLK_GET_FMAX_AT_VMIN | 4 |
+ * | #MRQ_QUERY_ABI | - | 4 |
+ * | #MRQ_PG | #CMD_PG_QUERY_ABI | 12 |
+ * | #MRQ_PG | #CMD_PG_SET_STATE | 12 |
+ * | #MRQ_PG | #CMD_PG_GET_STATE | 8 |
+ * | #MRQ_PG | #CMD_PG_GET_NAME | 8 |
+ * | #MRQ_PG | #CMD_PG_GET_MAX_ID | 8 |
+ * | #MRQ_THERMAL | #CMD_THERMAL_QUERY_ABI | 8 |
+ * | #MRQ_THERMAL | #CMD_THERMAL_GET_TEMP | 8 |
+ * | #MRQ_THERMAL | #CMD_THERMAL_GET_NUM_ZONES | 4 |
+ * | #MRQ_THERMAL | #CMD_THERMAL_GET_THERMTRIP | 8 |
+ * | #MRQ_ABI_RATCHET | - | 2 |
+ * | #MRQ_EMC_DVFS_LATENCY | - | 8 |
+ * | #MRQ_QUERY_FW_TAG | - | 0 |
+ * | #MRQ_DEBUG | #CMD_DEBUG_OPEN_RO | 4 + length of cmd_debug_fopen_request.name |
+ * | #MRQ_DEBUG | #CMD_DEBUG_OPEN_WO | 4 + length of cmd_debug_fopen_request.name |
+ * | #MRQ_DEBUG | #CMD_DEBUG_READ | 8 |
+ * | #MRQ_DEBUG | #CMD_DEBUG_WRITE | 12 + cmd_debug_fwrite_request.datalen |
+ * | #MRQ_DEBUG | #CMD_DEBUG_CLOSE | 8 |
+ *
+ * @cond (bpmp_t186)
+ * The following additional MRQ is supported on T186 -platform:
+ *
+ * | MRQ | Sub-command | Minimum payload length |
+ * | --------------------- | ------------------------------------- | ------------------------------------- |
+ * | #MRQ_CPU_VHINT | - | 8 |
+ * | #MRQ_THERMAL | #CMD_THERMAL_SET_TRIP | 20 |
+ * | #MRQ_RINGBUF_CONSOLE | #CMD_RINGBUF_CONSOLE_QUERY_ABI | 8 |
+ * | #MRQ_RINGBUF_CONSOLE | #CMD_RINGBUF_CONSOLE_READ | 5 |
+ * | #MRQ_RINGBUF_CONSOLE | #CMD_RINGBUF_CONSOLE_WRITE | 5 + cmd_ringbuf_console_write_req.len |
+ * | #MRQ_RINGBUF_CONSOLE | #CMD_RINGBUF_CONSOLE_GET_FIFO | 4 |
+ * @endcond
+ *
+ * @cond (bpmp_t194)
+ * The following additional MRQs are supported on T194 -platform:
+ *
+ * | MRQ | Sub-command | Minimum payload length |
+ * | --------------------- | ------------------------------------- | ------------------------------------- |
+ * | #MRQ_CPU_NDIV_LIMITS | - | 4 |
+ * | #MRQ_STRAP | #STRAP_SET | 12 |
+ * | #MRQ_CPU_AUTO_CC3 | - | 4 |
+ * | #MRQ_EC | #CMD_EC_STATUS_EX_GET | 12 |
+ * | #MRQ_FMON | #CMD_FMON_GEAR_CLAMP | 16 |
+ * | #MRQ_FMON | #CMD_FMON_GEAR_FREE | 4 |
+ * | #MRQ_FMON | #CMD_FMON_GEAR_GET | 4 |
+ * | #MRQ_FMON | #CMD_FMON_FAULT_STS_GET | 8 |
+ * | #MRQ_THERMAL | #CMD_THERMAL_SET_TRIP | 20 |
+ * | #MRQ_RINGBUF_CONSOLE | #CMD_RINGBUF_CONSOLE_QUERY_ABI | 8 |
+ * | #MRQ_RINGBUF_CONSOLE | #CMD_RINGBUF_CONSOLE_READ | 5 |
+ * | #MRQ_RINGBUF_CONSOLE | #CMD_RINGBUF_CONSOLE_WRITE | 5 + cmd_ringbuf_console_write_req.len |
+ * | #MRQ_RINGBUF_CONSOLE | #CMD_RINGBUF_CONSOLE_GET_FIFO | 4 |
+ * | #MRQ_UPHY | #CMD_UPHY_PCIE_LANE_MARGIN_CONTROL | 24 |
+ * | #MRQ_UPHY | #CMD_UPHY_PCIE_LANE_MARGIN_STATUS | 4 |
+ * | #MRQ_UPHY | #CMD_UPHY_PCIE_EP_CONTROLLER_PLL_INIT | 5 |
+ * | #MRQ_UPHY | #CMD_UPHY_PCIE_CONTROLLER_STATE | 6 |
+ * | #MRQ_UPHY | #CMD_UPHY_PCIE_EP_CONTROLLER_PLL_OFF | 5 |
+ * @endcond
+ *
+ * @cond (bpmp_safe && bpmp_t234)
+ * The following additional MRQ is supported on functional-safety
+ * builds for the T234 platform:
+ *
+ * | MRQ | Sub-command | Minimum payload length |
+ * | --------------------- | ------------------------------------- | ------------------------------------- |
+ * | #MRQ_CPU_NDIV_LIMITS | - | 4 |
+ * | #MRQ_RINGBUF_CONSOLE | #CMD_RINGBUF_CONSOLE_QUERY_ABI | 8 |
+ * | #MRQ_RINGBUF_CONSOLE | #CMD_RINGBUF_CONSOLE_READ | 5 |
+ * | #MRQ_RINGBUF_CONSOLE | #CMD_RINGBUF_CONSOLE_WRITE | 5 + cmd_ringbuf_console_write_req.len |
+ * | #MRQ_RINGBUF_CONSOLE | #CMD_RINGBUF_CONSOLE_GET_FIFO | 4 |
+ * | #MRQ_UPHY | #CMD_UPHY_PCIE_LANE_MARGIN_CONTROL | 24 |
+ * | #MRQ_UPHY | #CMD_UPHY_PCIE_LANE_MARGIN_STATUS | 4 |
+ * | #MRQ_UPHY | #CMD_UPHY_PCIE_EP_CONTROLLER_PLL_INIT | 5 |
+ * | #MRQ_UPHY | #CMD_UPHY_PCIE_CONTROLLER_STATE | 6 |
+ * | #MRQ_UPHY | #CMD_UPHY_PCIE_EP_CONTROLLER_PLL_OFF | 5 |
+ * | #MRQ_FMON | #CMD_FMON_GEAR_CLAMP | 16 |
+ * | #MRQ_FMON | #CMD_FMON_GEAR_FREE | 4 |
+ * | #MRQ_FMON | #CMD_FMON_GEAR_GET | 4 |
+ * | #MRQ_FMON | #CMD_FMON_FAULT_STS_GET | 8 |
+ * | #MRQ_EMC_DVFS_EMCHUB | - | 8 |
+ * | #MRQ_EMC_DISP_RFL | - | 4 |
+ *
+ * @endcond
+ *
+ * @cond (!bpmp_safe && bpmp_t234)
+ *
+ * The following additional MRQs are supported on non-functional-safety
+ * builds for the T234 and T238 -platforms:
+ *
+ * | MRQ | Sub-command | Minimum payload length |
+ * | --------------------- | ------------------------------------- | --------------------------------------------------- |
+ * | #MRQ_CPU_NDIV_LIMITS | - | 4 |
+ * | #MRQ_STRAP | #STRAP_SET | 12 |
+ * | #MRQ_THERMAL | #CMD_THERMAL_SET_TRIP | 20 |
+ * | #MRQ_RINGBUF_CONSOLE | #CMD_RINGBUF_CONSOLE_QUERY_ABI | 8 |
+ * | #MRQ_RINGBUF_CONSOLE | #CMD_RINGBUF_CONSOLE_READ | 5 |
+ * | #MRQ_RINGBUF_CONSOLE | #CMD_RINGBUF_CONSOLE_WRITE | 5 + cmd_ringbuf_console_write_req.len |
+ * | #MRQ_RINGBUF_CONSOLE | #CMD_RINGBUF_CONSOLE_GET_FIFO | 4 |
+ * | #MRQ_UPHY | #CMD_UPHY_PCIE_LANE_MARGIN_CONTROL | 24 |
+ * | #MRQ_UPHY | #CMD_UPHY_PCIE_LANE_MARGIN_STATUS | 4 |
+ * | #MRQ_UPHY | #CMD_UPHY_PCIE_EP_CONTROLLER_PLL_INIT | 5 |
+ * | #MRQ_UPHY | #CMD_UPHY_PCIE_CONTROLLER_STATE | 6 |
+ * | #MRQ_UPHY | #CMD_UPHY_PCIE_EP_CONTROLLER_PLL_OFF | 5 |
+ * | #MRQ_FMON | #CMD_FMON_GEAR_CLAMP | 16 |
+ * | #MRQ_FMON | #CMD_FMON_GEAR_FREE | 4 |
+ * | #MRQ_FMON | #CMD_FMON_GEAR_GET | 4 |
+ * | #MRQ_FMON | #CMD_FMON_FAULT_STS_GET | 8 |
+ * | #MRQ_EMC_DVFS_EMCHUB | - | 8 |
+ * | #MRQ_EMC_DISP_RFL | - | 4 |
+ * | #MRQ_BWMGR | #CMD_BWMGR_QUERY_ABI | 8 |
+ * | #MRQ_BWMGR | #CMD_BWMGR_CALC_RATE | 8 + 8 * cmd_bwmgr_calc_rate_request.num_iso_clients |
+ * | #MRQ_ISO_CLIENT | #CMD_ISO_CLIENT_QUERY_ABI | 8 |
+ * | #MRQ_ISO_CLIENT | #CMD_ISO_CLIENT_CALCULATE_LA | 16 |
+ * | #MRQ_ISO_CLIENT | #CMD_ISO_CLIENT_SET_LA | 16 |
+ * | #MRQ_ISO_CLIENT | #CMD_ISO_CLIENT_GET_MAX_BW | 8 |
+ * | #MRQ_BWMGR_INT | #CMD_BWMGR_INT_QUERY_ABI | 8 |
+ * | #MRQ_BWMGR_INT | #CMD_BWMGR_INT_CALC_AND_SET | 16 |
+ * | #MRQ_BWMGR_INT | #CMD_BWMGR_INT_CAP_SET | 8 |
+ * | #MRQ_BWMGR_INT | #CMD_BWMGR_INT_GET_LAST_REQUEST | 9 |
+ * | #MRQ_OC_STATUS | - | 0 |
+ * @endcond
+ *
+ * @cond bpmp_t238
+ * The following additional MRQs are supported on T238 platform:
+ *
+ * | MRQ | Sub-command | Minimum payload length |
+ * | --------------------- | ------------------------------------- | --------------------------------------------------- |
+ * | #MRQ_CPU_NDIV_LIMITS | - | 4 |
+ * | #MRQ_STRAP | #STRAP_SET | 12 |
+ * | #MRQ_THERMAL | #CMD_THERMAL_SET_TRIP | 20 |
+ * | #MRQ_RINGBUF_CONSOLE | #CMD_RINGBUF_CONSOLE_QUERY_ABI | 8 |
+ * | #MRQ_RINGBUF_CONSOLE | #CMD_RINGBUF_CONSOLE_READ | 5 |
+ * | #MRQ_RINGBUF_CONSOLE | #CMD_RINGBUF_CONSOLE_WRITE | 5 + cmd_ringbuf_console_write_req.len |
+ * | #MRQ_RINGBUF_CONSOLE | #CMD_RINGBUF_CONSOLE_GET_FIFO | 4 |
+ * | #MRQ_UPHY | #CMD_UPHY_PCIE_LANE_MARGIN_CONTROL | 24 |
+ * | #MRQ_UPHY | #CMD_UPHY_PCIE_LANE_MARGIN_STATUS | 4 |
+ * | #MRQ_UPHY | #CMD_UPHY_PCIE_EP_CONTROLLER_PLL_INIT | 5 |
+ * | #MRQ_UPHY | #CMD_UPHY_PCIE_CONTROLLER_STATE | 6 |
+ * | #MRQ_UPHY | #CMD_UPHY_PCIE_EP_CONTROLLER_PLL_OFF | 5 |
+ * | #MRQ_FMON | #CMD_FMON_GEAR_CLAMP | 16 |
+ * | #MRQ_FMON | #CMD_FMON_GEAR_FREE | 4 |
+ * | #MRQ_FMON | #CMD_FMON_GEAR_GET | 4 |
+ * | #MRQ_FMON | #CMD_FMON_FAULT_STS_GET | 8 |
+ * | #MRQ_EMC_DVFS_EMCHUB | - | 8 |
+ * | #MRQ_EMC_DISP_RFL | - | 4 |
+ * | #MRQ_BWMGR | #CMD_BWMGR_QUERY_ABI | 8 |
+ * | #MRQ_BWMGR | #CMD_BWMGR_CALC_RATE | 8 + 8 * cmd_bwmgr_calc_rate_request.num_iso_clients |
+ * | #MRQ_ISO_CLIENT | #CMD_ISO_CLIENT_QUERY_ABI | 8 |
+ * | #MRQ_ISO_CLIENT | #CMD_ISO_CLIENT_CALCULATE_LA | 16 |
+ * | #MRQ_ISO_CLIENT | #CMD_ISO_CLIENT_SET_LA | 16 |
+ * | #MRQ_ISO_CLIENT | #CMD_ISO_CLIENT_GET_MAX_BW | 8 |
+ * | #MRQ_BWMGR_INT | #CMD_BWMGR_INT_QUERY_ABI | 8 |
+ * | #MRQ_BWMGR_INT | #CMD_BWMGR_INT_CALC_AND_SET | 16 |
+ * | #MRQ_BWMGR_INT | #CMD_BWMGR_INT_CAP_SET | 8 |
+ * | #MRQ_BWMGR_INT | #CMD_BWMGR_INT_GET_LAST_REQUEST | 9 |
+ * | #MRQ_OC_STATUS | - | 0 |
+ * | #MRQ_THROTTLE | #CMD_THROTTLE_SET_OC_CONFIG | 5 |
+ * @endcond
+ *
+ * @cond (bpmp_th500)
+ * The following additional MRQs are supported on TH500 -platform:
+ *
+ * | MRQ | Sub-command | Minimum payload length |
+ * | -------------------- | ------------------------------------- | ---------------------- |
+ * | #MRQ_CPU_NDIV_LIMITS | - | 4 |
+ * | #MRQ_THERMAL | #CMD_THERMAL_SET_TRIP | 20 |
+ * | #MRQ_STRAP | #STRAP_SET | 12 |
+ * | #MRQ_SHUTDOWN | - | 4 |
+ * | #MRQ_UPHY | #CMD_UPHY_PCIE_LANE_MARGIN_CONTROL | 24 |
+ * | #MRQ_UPHY | #CMD_UPHY_PCIE_LANE_MARGIN_STATUS | 4 |
+ * | #MRQ_UPHY | #CMD_UPHY_PCIE_EP_CONTROLLER_PLL_INIT | 5 |
+ * | #MRQ_UPHY | #CMD_UPHY_PCIE_CONTROLLER_STATE | 6 |
+ * | #MRQ_UPHY | #CMD_UPHY_PCIE_EP_CONTROLLER_PLL_OFF | 5 |
+ * | #MRQ_UPHY | #CMD_UPHY_PCIE_CONFIG_VDM | 3 |
+ * | #MRQ_TELEMETRY | - | 8 |
+ * | #MRQ_PWR_LIMIT | #CMD_PWR_LIMIT_QUERY_ABI | 8 |
+ * | #MRQ_PWR_LIMIT | #CMD_PWR_LIMIT_SET | 20 |
+ * | #MRQ_PWR_LIMIT | #CMD_PWR_LIMIT_GET | 16 |
+ * | #MRQ_PWR_LIMIT | #CMD_PWR_LIMIT_CURR_CAP | 8 |
+ * | #MRQ_GEARS | - | 0 |
+ * | #MRQ_C2C | #CMD_C2C_QUERY_ABI | 8 |
+ * | #MRQ_C2C | #CMD_C2C_START_INITIALIZATION | 5 |
+ * | #MRQ_C2C | #CMD_C2C_GET_STATUS | 4 |
+ * | #MRQ_C2C | #CMD_C2C_HOTRESET_PREP | 5 |
+ * | #MRQ_C2C | #CMD_C2C_START_HOTRESET | 5 |
+ * | #MRQ_THROTTLE | #CMD_THROTTLE_QUERY_ABI | 4 |
+ * | #MRQ_THROTTLE | #CMD_THROTTLE_GET_CHIPTHROT_STATUS | 4 |
+ * | #MRQ_PWRMODEL | #CMD_PWRMODEL_QUERY_ABI | 8 |
+ * | #MRQ_PWRMODEL | #CMD_PWRMODEL_PWR_GET | 16 |
+ * | #MRQ_PWR_CNTRL | #CMD_PWR_CNTRL_QUERY_ABI | 8 |
+ * | #MRQ_PWR_CNTRL | #CMD_PWR_CNTRL_BYPASS_SET | 12 |
+ * | #MRQ_PWR_CNTRL | #CMD_PWR_CNTRL_BYPASS_GET | 8 |
+ * @endcond
+ *
+ * @cond (bpmp_tb500)
+ * The following additional MRQs are supported on TB500 -platform:
+ *
+ * | MRQ | Sub-command | Minimum payload length |
+ * | -------------------- | ---------------------------------------- | ---------------------- |
+ * | #MRQ_PWR_LIMIT | #CMD_PWR_LIMIT_QUERY_ABI | 8 |
+ * | #MRQ_PWR_LIMIT | #CMD_PWR_LIMIT_SET | 20 |
+ * | #MRQ_PWR_LIMIT | #CMD_PWR_LIMIT_GET | 16 |
+ * | #MRQ_PWR_LIMIT | #CMD_PWR_LIMIT_CURR_CAP | 8 |
+ * | #MRQ_TELEMETRY_EX | #CMD_TELEMETRY_EX_QUERY_ABI | 8 |
+ * | #MRQ_TELEMETRY_EX | #CMD_TELEMETRY_EX_BASE_SZ_GET | 12 |
+ * | #MRQ_THROTTLE | #CMD_THROTTLE_GET_CHIPTHROT_STATUS | 4 |
+ * | #MRQ_C2C | #CMD_C2C_QUERY_ABI | 8 |
+ * | #MRQ_C2C | #CMD_C2C_START_INITIALIZATION | 5 |
+ * | #MRQ_C2C | #CMD_C2C_GET_STATUS | 4 |
+ * | #MRQ_C2C | #CMD_C2C_HOTRESET_PREP | 5 |
+ * | #MRQ_C2C | #CMD_C2C_START_HOTRESET | 5 |
+ * | MRQ_HWPM | CMD_HWPM_QUERY_ABI | 4 |
+ * | MRQ_HWPM | CMD_HWPM_IPMU_SET_TRIGGERS | 120 |
+ * | MRQ_HWPM | CMD_HWPM_IPMU_SET_PAYLOADS_SHIFTS | 120 |
+ * | MRQ_HWPM | CMD_HWPM_IPMU_GET_MAX_PAYLOADS | 0 |
+ * | MRQ_HWPM | CMD_HWPM_NVTHERM_SET_SAMPLE_RATE | 4 |
+ * | MRQ_HWPM | CMD_HWPM_NVTHERM_SET_BUBBLE_INTERVAL | 4 |
+ * | MRQ_HWPM | CMD_HWPM_NVTHERM_SET_FLEX_CHANNELS | 120 |
+ * | MRQ_HWPM | CMD_HWPM_ISENSE_GET_SENSOR_NAME | 4 |
+ * | MRQ_HWPM | CMD_HWPM_ISENSE_GET_SENSOR_CHANNEL | 4 |
+ * | MRQ_HWPM | CMD_HWPM_ISENSE_GET_SENSOR_SCALE_FACTOR | 4 |
+ * | MRQ_HWPM | CMD_HWPM_ISENSE_GET_SENSOR_OFFSET | 4 |
+ * | MRQ_HWPM | CMD_HWPM_ISENSE_GET_SUM_BLOCK_NAME | 4 |
+ * | MRQ_HWPM | CMD_HWPM_ISENSE_GET_SUM_BLOCK_INPUTS | 4 |
+ * | MRQ_DVFS | CMD_DVFS_QUERY_ABI | 4 |
+ * | MRQ_DVFS | CMD_DVFS_SET_CTRL_STATE | 8 |
+ * | MRQ_DVFS | CMD_DVFS_SET_MGR_STATE | 8 |
+ * | MRQ_PPP_PROFILE | CMD_PPP_PROFILE_QUERY_ABI | 8 |
+ * | MRQ_PPP_PROFILE | CMD_PPP_PROFILE_QUERY_MASKS | 8 |
+ * | MRQ_PPP_PROFILE | CMD_PPP_CORE_QUERY_CPU_MASK | 8 |
+ * | MRQ_PPP_PROFILE | CMD_PPP_AVAILABLE_QUERY | 4 |
+ * @endcond
+ *
+ * @cond (bpmp_safe && bpmp_t264)
+ * The following additional MRQ is supported on functional-safety
+ * builds for the T264 platform:
+ *
+ * | MRQ | Sub-command | Minimum payload length |
+ * | -------------------- | --------------------------------- | ---------------------- |
+ * | #MRQ_CPU_NDIV_LIMITS | - | 4 |
+ * | #MRQ_STRAP | #STRAP_SET | 12 |
+ * | #MRQ_SHUTDOWN | - | 4 |
+ * | #MRQ_FMON | #CMD_FMON_GEAR_CLAMP | 16 |
+ * | #MRQ_FMON | #CMD_FMON_GEAR_FREE | 4 |
+ * | #MRQ_FMON | #CMD_FMON_GEAR_GET | 4 |
+ * | #MRQ_FMON | #CMD_FMON_FAULT_STS_GET | 8 |
+ * | #MRQ_PCIE | #CMD_PCIE_EP_CONTROLLER_INIT | 5 |
+ * | #MRQ_PCIE | #CMD_PCIE_EP_CONTROLLER_OFF | 5 |
+ * | #MRQ_CR7 | #CMD_CR7_ENTRY | 12 |
+ * | #MRQ_CR7 | #CMD_CR7_EXIT | 12 |
+ * | #MRQ_SLC | #CMD_SLC_QUERY_ABI | 8 |
+ * | #MRQ_SLC | #CMD_SLC_BYPASS_SET | 8 |
+ * | #MRQ_SLC | #CMD_SLC_BYPASS_GET | 4 |
+ * @endcond
+ *
+ * @cond (!bpmp_safe && bpmp_t264)
+ * The following additional MRQs are supported on non-functional-safety
+ * builds for the T264 -platform:
+ *
+ * | MRQ | Sub-command | Minimum payload length |
+ * | -------------------- | --------------------------------- | ---------------------- |
+ * | #MRQ_CPU_NDIV_LIMITS | - | 4 |
+ * | #MRQ_STRAP | #STRAP_SET | 12 |
+ * | #MRQ_SHUTDOWN | - | 4 |
+ * | #MRQ_FMON | #CMD_FMON_GEAR_CLAMP | 16 |
+ * | #MRQ_FMON | #CMD_FMON_GEAR_FREE | 4 |
+ * | #MRQ_FMON | #CMD_FMON_GEAR_GET | 4 |
+ * | #MRQ_FMON | #CMD_FMON_FAULT_STS_GET | 8 |
+ * | #MRQ_OC_STATUS | - | 0 |
+ * | #MRQ_PCIE | #CMD_PCIE_EP_CONTROLLER_INIT | 5 |
+ * | #MRQ_PCIE | #CMD_PCIE_EP_CONTROLLER_OFF | 5 |
+ * | #MRQ_PCIE | #CMD_PCIE_RP_CONTROLLER_OFF | 5 |
+ * | #MRQ_CR7 | #CMD_CR7_ENTRY | 12 |
+ * | #MRQ_CR7 | #CMD_CR7_EXIT | 12 |
+ * | #MRQ_SLC | #CMD_SLC_QUERY_ABI | 8 |
+ * | #MRQ_SLC | #CMD_SLC_BYPASS_SET | 8 |
+ * | #MRQ_SLC | #CMD_SLC_BYPASS_GET | 4 |
+ * | #MRQ_ISO_CLIENT | #CMD_ISO_CLIENT_QUERY_ABI | 8 |
+ * | #MRQ_ISO_CLIENT | #CMD_ISO_CLIENT_CALCULATE_LA | 16 |
+ * | #MRQ_ISO_CLIENT | #CMD_ISO_CLIENT_SET_LA | 16 |
+ * | #MRQ_ISO_CLIENT | #CMD_ISO_CLIENT_GET_MAX_BW | 8 |
+ * | #MRQ_BWMGR_INT | #CMD_BWMGR_INT_QUERY_ABI | 8 |
+ * | #MRQ_BWMGR_INT | #CMD_BWMGR_INT_CALC_AND_SET | 16 |
+ * | #MRQ_BWMGR_INT | #CMD_BWMGR_INT_CAP_SET | 8 |
+ * | #MRQ_BWMGR_INT | #CMD_BWMGR_INT_CURR_AVAILABLE_BW | 8 |
+ * | #MRQ_BWMGR_INT | #CMD_BWMGR_INT_GET_LAST_REQUEST | 9 |
+ * @endcond
*
* **crc16**
*
@@ -220,7 +452,7 @@ struct mrq_request {
* including this header. However the crc16 field is considered to be set to 0 when
* calculating the CRC. Only used when #BPMP_MAIL_CRC_PRESENT is set. If
* #BPMP_MAIL_CRC_PRESENT is set and this field does not match the CRC as
- * calculated by BPMP, -BPMP_EBADMSG will be returned and the request will
+ * calculated by BPMP, -#BPMP_EBADMSG will be returned and the request will
* be ignored. See code snippet below on how to calculate the CRC.
*
* @code
@@ -322,6 +554,9 @@ struct mrq_response {
#define MRQ_CPU_VHINT 28U
#define MRQ_ABI_RATCHET 29U
#define MRQ_EMC_DVFS_LATENCY 31U
+//adoc: tag::bpmp_dmce_mrq_shutdown[]
+#define MRQ_SHUTDOWN 49U
+//adoc: end::bpmp_dmce_mrq_shutdown[]
#define MRQ_RINGBUF_CONSOLE 65U
#define MRQ_PG 66U
#define MRQ_CPU_NDIV_LIMITS 67U
@@ -341,48 +576,31 @@ struct mrq_response {
#define MRQ_GEARS 82U
#define MRQ_BWMGR_INT 83U
#define MRQ_OC_STATUS 84U
-
-/** @cond DEPRECATED */
-#define MRQ_RESERVED_2 2U
-#define MRQ_RESERVED_3 3U
-#define MRQ_RESERVED_4 4U
-#define MRQ_RESERVED_5 5U
-#define MRQ_RESERVED_6 6U
-#define MRQ_RESERVED_7 7U
-#define MRQ_RESERVED_8 8U
-#define MRQ_RESERVED_10 10U
-#define MRQ_RESERVED_11 11U
-#define MRQ_RESERVED_12 12U
-#define MRQ_RESERVED_13 13U
-#define MRQ_RESERVED_14 14U
-#define MRQ_RESERVED_15 15U
-#define MRQ_RESERVED_16 16U
-#define MRQ_RESERVED_17 17U
-#define MRQ_RESERVED_18 18U
-#define MRQ_RESERVED_24 24U
-#define MRQ_RESERVED_25 25U
-#define MRQ_RESERVED_26 26U
-#define MRQ_RESERVED_30 30U
-#define MRQ_RESERVED_64 64U
-#define MRQ_RESERVED_74 74U
-/** @endcond DEPRECATED */
-
-/** @} */
+#define MRQ_C2C 85U
+#define MRQ_THROTTLE 86U
+#define MRQ_PWRMODEL 87U
+#define MRQ_PCIE 88U
+#define MRQ_PWR_CNTRL 89U
+#define MRQ_CR7 90U
+#define MRQ_SLC 91U
+#define MRQ_TELEMETRY_EX 92U
+#define MRQ_HWPM 93U
+#define MRQ_DVFS 94U
+#define MRQ_PPP_PROFILE 95U
/**
- * @ingroup MRQ_Codes
* @brief Maximum MRQ code to be sent by CPU software to
* BPMP. Subject to change in future
*/
-#define MAX_CPU_MRQ_ID 84U
+#define MAX_CPU_MRQ_ID 95U
+
+/** @} */
/**
* @addtogroup MRQ_Payloads
* @{
* @defgroup Ping Ping
* @defgroup Query_Tag Query Tag
- * @defgroup Module Loadable Modules
- * @defgroup Trace Trace
* @defgroup Debugfs Debug File System
* @defgroup Reset Reset
* @defgroup I2C I2C
@@ -390,6 +608,7 @@ struct mrq_response {
* @defgroup ABI_info ABI Info
* @defgroup Powergating Power Gating
* @defgroup Thermal Thermal
+ * @defgroup Throttle Throttle
* @defgroup OC_status OC status
* @defgroup Vhint CPU Voltage hint
* @defgroup EMC EMC
@@ -405,7 +624,22 @@ struct mrq_response {
* @defgroup Telemetry Telemetry
* @defgroup Pwrlimit PWR_LIMIT
* @defgroup Gears Gears
+ * @defgroup Shutdown Shutdown
* @defgroup BWMGR_INT Bandwidth Manager Integrated
+ * @defgroup C2C C2C
+ * @defgroup Pwrmodel Power Model
+ * @defgroup Pwrcntrl Power Controllers
+ * @cond bpmp_t264
+ * * @defgroup PCIE PCIE
+ * * @defgroup CR7 CR7
+ * * @defgroup Slc Slc
+ * @endcond
+ * @cond bpmp_tb500
+ * * @defgroup Telemetry_ex Telemetry Expanded
+ * * @defgroup HWPM Hardware Performance Monitoring
+ * * @defgroup DVFS Dynamic Voltage and Frequency Scaling
+ * * @defgroup PPP power/performance profiles
+ * @endcond
* @} MRQ_Payloads
*/
@@ -414,7 +648,6 @@ struct mrq_response {
* @def MRQ_PING
* @brief A simple ping
*
- * * Platforms: All
* * Initiators: Any
* * Targets: Any
* * Request Payload: @ref mrq_ping_request
@@ -424,7 +657,6 @@ struct mrq_response {
* @def MRQ_THREADED_PING
* @brief A deeper ping
*
- * * Platforms: All
* * Initiators: Any
* * Targets: BPMP
* * Request Payload: @ref mrq_ping_request
@@ -441,8 +673,8 @@ struct mrq_response {
* @brief Request with #MRQ_PING
*
* Used by the sender of an #MRQ_PING message to request a pong from
- * recipient. The response from the recipient is computed based on
- * #challenge.
+ * recipient. The response from the recipient is computed based on the
+ * mrq_ping_request::challenge -value.
*/
struct mrq_ping_request {
/** @brief Arbitrarily chosen value */
@@ -470,7 +702,7 @@ struct mrq_ping_response {
*
* @deprecated Use #MRQ_QUERY_FW_TAG instead.
*
- * * Platforms: All
+ * @details
* * Initiators: CCPLEX
* * Targets: BPMP
* * Request Payload: @ref mrq_query_tag_request
@@ -483,7 +715,7 @@ struct mrq_ping_response {
* @brief Request with #MRQ_QUERY_TAG
*
* @deprecated This structure will be removed in future version.
- * Use MRQ_QUERY_FW_TAG instead.
+ * Use #MRQ_QUERY_FW_TAG instead.
*/
struct mrq_query_tag_request {
/** @brief Base address to store the firmware tag */
@@ -496,7 +728,6 @@ struct mrq_query_tag_request {
* @def MRQ_QUERY_FW_TAG
* @brief Query BPMP firmware's tag (i.e. unique identifier)
*
- * * Platforms: All
* * Initiators: Any
* * Targets: BPMP
* * Request Payload: N/A
@@ -510,10 +741,9 @@ struct mrq_query_tag_request {
*
* Sent in response to #MRQ_QUERY_FW_TAG message. #tag contains the unique
* identifier for the version of firmware issuing the reply.
- *
*/
struct mrq_query_fw_tag_response {
- /** @brief Array to store tag information */
+ /** @brief Array to store tag information */
uint8_t tag[32];
} BPMP_ABI_PACKED;
@@ -532,9 +762,8 @@ struct mrq_threaded_ping_response {
* @def MRQ_DEBUGFS
* @brief Interact with BPMP's debugfs file nodes
*
- * @deprecated use MRQ_DEBUG instead.
+ * @deprecated Use #MRQ_DEBUG instead.
*
- * * Platforms: T186, T194
* * Initiators: Any
* * Targets: BPMP
* * Request Payload: @ref mrq_debugfs_request
@@ -626,9 +855,9 @@ struct cmd_debugfs_dumpdir_response {
/**
* @ingroup Debugfs
- * @brief Request with #MRQ_DEBUGFS.
+ * @brief Request with #MRQ_DEBUG.
*
- * The sender of an MRQ_DEBUGFS message uses #cmd to specify a debugfs
+ * The sender of an MRQ_DEBUG message uses #cmd to specify a debugfs
* command to execute. Legal commands are the values of @ref
* mrq_debugfs_commands. Each command requires a specific additional
* payload of data.
@@ -676,16 +905,15 @@ struct mrq_debugfs_response {
/**
* @ingroup MRQ_Codes
* @def MRQ_DEBUG
- * @brief Interact with BPMP's debugfs file nodes. Use message payload
+ * @brief Interact with BPMP-FW debugfs file nodes. Use message payload
* for exchanging data. This is functionally equivalent to
- * @ref MRQ_DEBUGFS. But the way in which data is exchanged is different.
- * When software running on CPU tries to read a debugfs file,
+ * the deprecated MRQ_DEBUGFS but the way in which data is exchanged is
+ * different. When software running on CPU tries to read a debugfs file,
* the file path and read data will be stored in message payload.
* Since the message payload size is limited, a debugfs file
* transaction might require multiple frames of data exchanged
* between BPMP and CPU until the transaction completes.
*
- * * Platforms: T194
* * Initiators: Any
* * Targets: BPMP
* * Request Payload: @ref mrq_debug_request
@@ -694,17 +922,34 @@ struct mrq_debugfs_response {
/** @ingroup Debugfs */
enum mrq_debug_commands {
- /** @brief Open required file for read operation */
+ /**
+ * @brief Open file represented by the path in
+ * cmd_debug_fopen_request::name for read operation
+ */
CMD_DEBUG_OPEN_RO = 0,
- /** @brief Open required file for write operation */
+ /**
+ * @brief Open file represented by the path in
+ * cmd_debug_fopen_request::name for write operation
+ */
CMD_DEBUG_OPEN_WO = 1,
- /** @brief Perform read */
+ /**
+ * @brief Perform read on a previously opened file handle represented
+ * by the cmd_debug_fread_request::fd -value.
+ */
CMD_DEBUG_READ = 2,
- /** @brief Perform write */
+ /**
+ * @brief Perform write on a previously opened file handle represented
+ * by the cmd_debug_fwrite_request::fd -value.
+ */
CMD_DEBUG_WRITE = 3,
- /** @brief Close file */
+ /**
+ * @brief Close previously opened file handle.
+ */
CMD_DEBUG_CLOSE = 4,
- /** @brief Not a command */
+ /**
+ * @brief Not a command, represents maximum number of supported
+ * sub-commands
+ */
CMD_DEBUG_MAX
};
@@ -727,35 +972,38 @@ enum mrq_debug_commands {
/**
* @ingroup Debugfs
- * @brief Parameters for CMD_DEBUG_OPEN command
+ * @brief Parameters for #CMD_DEBUG_OPEN_RO and #CMD_DEBUG_OPEN_WO -commands
*/
struct cmd_debug_fopen_request {
- /** @brief File name - Null-terminated string with maximum
- * length @ref DEBUG_FNAME_MAX_SZ
+ /**
+ * @brief File name - Null-terminated string with maximum
+ * length including the terminator defined by the
+ * #DEBUG_FNAME_MAX_SZ -preprocessor constant.
*/
char name[DEBUG_FNAME_MAX_SZ];
} BPMP_ABI_PACKED;
/**
* @ingroup Debugfs
- * @brief Response data for CMD_DEBUG_OPEN_RO/WO command
+ * @brief Response data for #CMD_DEBUG_OPEN_RO and #CMD_DEBUG_OPEN_WO commands
*/
struct cmd_debug_fopen_response {
/** @brief Identifier for file access */
uint32_t fd;
/** @brief Data length. File data size for READ command.
- * Maximum allowed length for WRITE command
+ * Maximum allowed length for WRITE command
*/
uint32_t datalen;
} BPMP_ABI_PACKED;
/**
* @ingroup Debugfs
- * @brief Parameters for CMD_DEBUG_READ command
+ * @brief Parameters for #CMD_DEBUG_READ command
*/
struct cmd_debug_fread_request {
- /** @brief File access identifier received in response
- * to CMD_DEBUG_OPEN_RO request
+ /**
+ * @brief File access identifier received in response
+ * to #CMD_DEBUG_OPEN_RO request
*/
uint32_t fd;
} BPMP_ABI_PACKED;
@@ -770,7 +1018,7 @@ struct cmd_debug_fread_request {
/**
* @ingroup Debugfs
- * @brief Response data for CMD_DEBUG_READ command
+ * @brief Response data for #CMD_DEBUG_READ command
*/
struct cmd_debug_fread_response {
/** @brief Size of data provided in this response in bytes */
@@ -789,11 +1037,11 @@ struct cmd_debug_fread_response {
/**
* @ingroup Debugfs
- * @brief Parameters for CMD_DEBUG_WRITE command
+ * @brief Parameters for #CMD_DEBUG_WRITE command
*/
struct cmd_debug_fwrite_request {
/** @brief File access identifier received in response
- * to CMD_DEBUG_OPEN_RO request
+ * to prior #CMD_DEBUG_OPEN_RO -request
*/
uint32_t fd;
/** @brief Size of write data in bytes */
@@ -804,11 +1052,12 @@ struct cmd_debug_fwrite_request {
/**
* @ingroup Debugfs
- * @brief Parameters for CMD_DEBUG_CLOSE command
+ * @brief Parameters for #CMD_DEBUG_CLOSE command
*/
struct cmd_debug_fclose_request {
- /** @brief File access identifier received in response
- * to CMD_DEBUG_OPEN_RO request
+ /**
+ * @brief File access identifier received in prior response
+ * to #CMD_DEBUG_OPEN_RO or #CMD_DEBUG_OPEN_WO -request.
*/
uint32_t fd;
} BPMP_ABI_PACKED;
@@ -817,30 +1066,34 @@ struct cmd_debug_fclose_request {
* @ingroup Debugfs
* @brief Request with #MRQ_DEBUG.
*
- * The sender of an MRQ_DEBUG message uses #cmd to specify a debugfs
- * command to execute. Legal commands are the values of @ref
- * mrq_debug_commands. Each command requires a specific additional
- * payload of data.
+ * The sender of an #MRQ_DEBUG message uses mrq_debug_request::cmd to specify
+ * which debugfs sub-command to execute. Legal sub-commands are the values
+ * specified in the @ref mrq_debug_commands -enumeration. Each sub-command
+ * requires a specific additional payload of data according to the following
+ * table:
*
- * |command |payload|
- * |-------------------|-------|
- * |CMD_DEBUG_OPEN_RO |fop |
- * |CMD_DEBUG_OPEN_WO |fop |
- * |CMD_DEBUG_READ |frd |
- * |CMD_DEBUG_WRITE |fwr |
- * |CMD_DEBUG_CLOSE |fcl |
+ * |Sub-command |Payload structure |
+ * |--------------------|---------------------------|
+ * |#CMD_DEBUG_OPEN_RO |cmd_debug_fopen_request |
+ * |#CMD_DEBUG_OPEN_WO |cmd_debug_fopen_request |
+ * |#CMD_DEBUG_READ |cmd_debug_fread_request |
+ * |#CMD_DEBUG_WRITE |cmd_debug_fwrite_request |
+ * |#CMD_DEBUG_CLOSE |cmd_debug_fclose_request |
*/
struct mrq_debug_request {
- /** @brief Sub-command (@ref mrq_debug_commands) */
+ /** @brief Sub-command identifier from @ref mrq_debug_commands */
uint32_t cmd;
union {
- /** @brief Request payload for CMD_DEBUG_OPEN_RO/WO command */
+ /**
+ * @brief Request payload for #CMD_DEBUG_OPEN_RO and
+ * #CMD_DEBUG_OPEN_WO sub-commands
+ */
struct cmd_debug_fopen_request fop;
- /** @brief Request payload for CMD_DEBUG_READ command */
+ /** @brief Request payload for #CMD_DEBUG_READ sub-command */
struct cmd_debug_fread_request frd;
- /** @brief Request payload for CMD_DEBUG_WRITE command */
+ /** @brief Request payload for #CMD_DEBUG_WRITE sub-command */
struct cmd_debug_fwrite_request fwr;
- /** @brief Request payload for CMD_DEBUG_CLOSE command */
+ /** @brief Request payload for #CMD_DEBUG_CLOSE sub-command */
struct cmd_debug_fclose_request fcl;
} BPMP_UNION_ANON;
} BPMP_ABI_PACKED;
@@ -850,9 +1103,12 @@ struct mrq_debug_request {
*/
struct mrq_debug_response {
union {
- /** @brief Response data for CMD_DEBUG_OPEN_RO/WO command */
+ /**
+ * @brief Response data for the #CMD_DEBUG_OPEN_RO and
+ * #CMD_DEBUG_OPEN_WO sub-commands
+ */
struct cmd_debug_fopen_response fop;
- /** @brief Response data for CMD_DEBUG_READ command */
+ /** @brief Response data for the #CMD_DEBUG_READ sub-command */
struct cmd_debug_fread_response frd;
} BPMP_UNION_ANON;
} BPMP_ABI_PACKED;
@@ -862,7 +1118,6 @@ struct mrq_debug_response {
* @def MRQ_RESET
* @brief Reset an IP block
*
- * * Platforms: T186, T194
* * Initiators: Any
* * Targets: BPMP
* * Request Payload: @ref mrq_reset_request
@@ -872,39 +1127,46 @@ struct mrq_debug_response {
* @{
*/
+/**
+ * @brief Sub-command identifiers for #MRQ_RESET
+ */
enum mrq_reset_commands {
/**
* @brief Assert module reset
*
- * mrq_response::err is 0 if the operation was successful, or @n
- * -#BPMP_EINVAL if mrq_reset_request::reset_id is invalid @n
- * -#BPMP_EACCES if mrq master is not an owner of target domain reset @n
- * -#BPMP_ENOTSUP if target domain h/w state does not allow reset
+ * mrq_response::err is
+ * * 0 if the operation was successful
+ * * -#BPMP_EINVAL if mrq_reset_request::reset_id is invalid
+ * * -#BPMP_EACCES if mrq master is not an owner of target domain reset
+ * * -#BPMP_ENOTSUP if target domain h/w state does not allow reset
*/
CMD_RESET_ASSERT = 1,
/**
* @brief Deassert module reset
*
- * mrq_response::err is 0 if the operation was successful, or @n
- * -#BPMP_EINVAL if mrq_reset_request::reset_id is invalid @n
- * -#BPMP_EACCES if mrq master is not an owner of target domain reset @n
- * -#BPMP_ENOTSUP if target domain h/w state does not allow reset
+ * mrq_response::err is
+ * * 0 if the operation was successful
+ * * -#BPMP_EINVAL if mrq_reset_request::reset_id is invalid
+ * * -#BPMP_EACCES if mrq master is not an owner of target domain reset
+ * * -#BPMP_ENOTSUP if target domain h/w state does not allow reset
*/
CMD_RESET_DEASSERT = 2,
/**
* @brief Assert and deassert the module reset
*
- * mrq_response::err is 0 if the operation was successful, or @n
- * -#BPMP_EINVAL if mrq_reset_request::reset_id is invalid @n
- * -#BPMP_EACCES if mrq master is not an owner of target domain reset @n
- * -#BPMP_ENOTSUP if target domain h/w state does not allow reset
+ * mrq_response::err is
+ * * 0 if the operation was successful
+ * * -#BPMP_EINVAL if mrq_reset_request::reset_id is invalid
+ * * -#BPMP_EACCES if mrq master is not an owner of target domain reset
+ * * -#BPMP_ENOTSUP if target domain h/w state does not allow reset
*/
CMD_RESET_MODULE = 3,
/**
* @brief Get the highest reset ID
*
- * mrq_response::err is 0 if the operation was successful, or @n
- * -#BPMP_ENODEV if no reset domains are supported (number of IDs is 0)
+ * mrq_response::err is
+ * * 0 if the operation was successful
+ * * -#BPMP_ENODEV if no reset domains are supported (number of IDs is 0)
*/
CMD_RESET_GET_MAX_ID = 4,
@@ -913,15 +1175,15 @@ enum mrq_reset_commands {
};
/**
- * @brief Request with MRQ_RESET
+ * @brief Request with #MRQ_RESET
*
* Used by the sender of an #MRQ_RESET message to request BPMP to
- * assert or or deassert a given reset line.
+ * assert or deassert a given reset line.
*/
struct mrq_reset_request {
- /** @brief Reset action to perform (@ref mrq_reset_commands) */
+ /** @brief Reset action to perform, from @ref mrq_reset_commands */
uint32_t cmd;
- /** @brief Id of the reset to affected */
+ /** @brief ID of the reset to affected, from @ref bpmp_reset_ids */
uint32_t reset_id;
} BPMP_ABI_PACKED;
@@ -940,7 +1202,7 @@ struct cmd_reset_get_max_id_response {
*
* Each sub-command supported by @ref mrq_reset_request may return
* sub-command-specific data. Some do and some do not as indicated
- * in the following table
+ * in the following table:
*
* | sub-command | payload |
* |----------------------|------------------|
@@ -962,7 +1224,6 @@ struct mrq_reset_response {
* @def MRQ_I2C
* @brief Issue an i2c transaction
*
- * * Platforms: T186, T194
* * Initiators: Any
* * Targets: BPMP
* * Request Payload: @ref mrq_i2c_request
@@ -971,19 +1232,60 @@ struct mrq_reset_response {
* @addtogroup I2C
* @{
*/
+
+/**
+ * @brief Size of the cmd_i2c_xfer_request::data_buf -member array in bytes.
+ */
#define TEGRA_I2C_IPC_MAX_IN_BUF_SIZE (MSG_DATA_MIN_SZ - 12U)
+
+/**
+ * @brief Size of the cmd_i2c_xfer_response::data_buf -member array in bytes.
+ */
#define TEGRA_I2C_IPC_MAX_OUT_BUF_SIZE (MSG_DATA_MIN_SZ - 4U)
+/**
+ * @defgroup seriali2c_flags I2C flags
+ *
+ * @brief I2C transaction modifier flags for each transaction segment
+ * in #MRQ_I2C subcommand CMD_I2C_XFER
+ */
+
+/**
+ * @addtogroup seriali2c_flags
+ * @{
+ */
+
+/** @brief when set, use 10-bit I2C slave address */
#define SERIALI2C_TEN 0x0010U
+/** @brief when set, perform a Read transaction */
#define SERIALI2C_RD 0x0001U
-#define SERIALI2C_STOP 0x8000U
+/**
+ * @brief when set, no repeated START is issued between the segments
+ * of transaction. This flag is ignored for the first segment as any
+ * transaction always starts with a START condition
+ */
#define SERIALI2C_NOSTART 0x4000U
-#define SERIALI2C_REV_DIR_ADDR 0x2000U
+/**
+ * @brief when set, a no-ACK from slave device is ignored and treated
+ * always as success
+ */
#define SERIALI2C_IGNORE_NAK 0x1000U
+/** @} seriali2c_flags */
+
+/** brief Unused flag. Retained for backwards compatibility. */
+#define SERIALI2C_STOP 0x8000U
+/** brief Unused flag. Retained for backwards compatibility. */
+#define SERIALI2C_REV_DIR_ADDR 0x2000U
+/** brief Unused flag. Retained for backwards compatibility. */
#define SERIALI2C_NO_RD_ACK 0x0800U
+/** brief Unused flag. Retained for backwards compatibility. */
#define SERIALI2C_RECV_LEN 0x0400U
-enum {
+/**
+ * @brief Supported I2C sub-command identifiers
+ */
+enum mrq_i2c_commands {
+ /** @brief Perform an I2C transaction */
CMD_I2C_XFER = 1
};
@@ -1005,7 +1307,7 @@ enum {
struct serial_i2c_request {
/** @brief I2C slave address */
uint16_t addr;
- /** @brief Bitmask of SERIALI2C_ flags */
+ /** @brief Bitmask of @ref seriali2c_flags */
uint16_t flags;
/** @brief Length of I2C transaction in bytes */
uint16_t len;
@@ -1020,13 +1322,13 @@ struct cmd_i2c_xfer_request {
/**
* @brief Tegra PWR_I2C bus identifier
*
- * @cond (bpmp_t234 || bpmp_t239 || bpmp_t194)
+ * @cond (bpmp_t186 || bpmp_t194 || bpmp_t234 || bpmp_t238 || bpmp_t264)
* Must be set to 5.
- * @endcond (bpmp_t234 || bpmp_t239 || bpmp_t194)
- * @cond bpmp_th500
- * Must be set to 1.
- * @endcond bpmp_th500
+ * @endcond
*
+ * @cond (bpmp_th500)
+ * Must be set to 1.
+ * @endcond
*/
uint32_t bus_id;
@@ -1047,7 +1349,7 @@ struct cmd_i2c_xfer_request {
struct cmd_i2c_xfer_response {
/** @brief Count of valid bytes in #data_buf*/
uint32_t data_size;
- /** @brief I2c read data */
+ /** @brief I2C read data */
uint8_t data_buf[TEGRA_I2C_IPC_MAX_OUT_BUF_SIZE];
} BPMP_ABI_PACKED;
@@ -1064,16 +1366,19 @@ struct mrq_i2c_request {
/**
* @brief Response to #MRQ_I2C
*
- * mrq_response:err is
- * 0: Success
- * -#BPMP_EBADCMD: if mrq_i2c_request::cmd is other than 1
- * -#BPMP_EINVAL: if cmd_i2c_xfer_request does not contain correctly formatted request
- * -#BPMP_ENODEV: if cmd_i2c_xfer_request::bus_id is not supported by BPMP
- * -#BPMP_EACCES: if i2c transaction is not allowed due to firewall rules
- * -#BPMP_ETIMEDOUT: if i2c transaction times out
- * -#BPMP_ENXIO: if i2c slave device does not reply with ACK to the transaction
- * -#BPMP_EAGAIN: if ARB_LOST condition is detected by the i2c controller
- * -#BPMP_EIO: any other i2c controller error code than NO_ACK or ARB_LOST
+ * mrq_response::err value for this response is defined as:
+ *
+ * | Value | Description |
+ * |--------------------|---------------------------------------------------------------------|
+ * | 0 | Success |
+ * | -#BPMP_EBADCMD | mrq_i2c_request::cmd is other than 1 |
+ * | -#BPMP_EINVAL | cmd_i2c_xfer_request does not contain correctly formatted request |
+ * | -#BPMP_ENODEV | cmd_i2c_xfer_request::bus_id is not supported by BPMP |
+ * | -#BPMP_EACCES | I2C transaction is not allowed due to firewall rules |
+ * | -#BPMP_ETIMEDOUT | I2C transaction times out |
+ * | -#BPMP_ENXIO | I2C slave device does not reply with ACK to the transaction |
+ * | -#BPMP_EAGAIN | ARB_LOST condition is detected by the I2C controller |
+ * | -#BPMP_EIO | Any other I2C controller error code than NO_ACK or ARB_LOST |
*/
struct mrq_i2c_response {
struct cmd_i2c_xfer_response xfer;
@@ -1086,7 +1391,6 @@ struct mrq_i2c_response {
* @def MRQ_CLK
* @brief Perform a clock operation
*
- * * Platforms: T186, T194
* * Initiators: Any
* * Targets: BPMP
* * Request Payload: @ref mrq_clk_request
@@ -1095,205 +1399,354 @@ struct mrq_i2c_response {
* @addtogroup Clocks
* @{
*/
-enum {
+
+/**
+ * @brief Sub-command identifiers for #MRQ_CLK
+ */
+enum mrq_clk_commands {
+ /** Get clock rate */
CMD_CLK_GET_RATE = 1,
+
+ /** Set clock rate */
CMD_CLK_SET_RATE = 2,
+
+ /** Get attainable clock rate closer to a given rate */
CMD_CLK_ROUND_RATE = 3,
+
+ /** Get parent clock identifier for a given clock */
CMD_CLK_GET_PARENT = 4,
+
+ /** Change clock parent */
CMD_CLK_SET_PARENT = 5,
+
+ /** Get clock enable status */
CMD_CLK_IS_ENABLED = 6,
+
+ /** Enable a clock */
CMD_CLK_ENABLE = 7,
+
+ /** Disable a clock */
CMD_CLK_DISABLE = 8,
-/** @cond DEPRECATED */
- CMD_CLK_PROPERTIES = 9,
- CMD_CLK_POSSIBLE_PARENTS = 10,
- CMD_CLK_NUM_POSSIBLE_PARENTS = 11,
- CMD_CLK_GET_POSSIBLE_PARENT = 12,
- CMD_CLK_RESET_REFCOUNTS = 13,
-/** @endcond DEPRECATED */
+
+ /** Get all information about a clock */
CMD_CLK_GET_ALL_INFO = 14,
+
+ /** Get largest supported clock identifier */
CMD_CLK_GET_MAX_CLK_ID = 15,
+
+ /** Get clock maximum rate at VMIN */
CMD_CLK_GET_FMAX_AT_VMIN = 16,
+
+ /** Largest supported #MRQ_CLK sub-command identifier + 1 */
CMD_CLK_MAX,
};
+/**
+ * Flag bit set in cmd_clk_get_all_info_response::flags -field when clock
+ * supports changing of the parent clock at runtime.
+ */
#define BPMP_CLK_HAS_MUX (1U << 0U)
+
+/**
+ * Flag bit set in cmd_clk_get_all_info_response::flags -field when clock
+ * supports changing the clock rate at runtime.
+ */
#define BPMP_CLK_HAS_SET_RATE (1U << 1U)
+
+/**
+ * Flag bit set in cmd_clk_get_all_info_response::flags -field when clock is a
+ * root clock without visible parents.
+ */
#define BPMP_CLK_IS_ROOT (1U << 2U)
+
#define BPMP_CLK_IS_VAR_ROOT (1U << 3U)
+
/**
* @brief Protection against rate and parent changes
*
- * #MRQ_CLK command #CMD_CLK_SET_RATE or #MRQ_CLK command #CMD_CLK_SET_PARENT will return
- * -#BPMP_EACCES.
+ * #MRQ_CLK command #CMD_CLK_SET_RATE or #MRQ_CLK command #CMD_CLK_SET_PARENT
+ * will return -#BPMP_EACCES.
*/
#define BPMP_CLK_RATE_PARENT_CHANGE_DENIED (1U << 30)
/**
* @brief Protection against state changes
*
- * #MRQ_CLK command #CMD_CLK_ENABLE or #MRQ_CLK command #CMD_CLK_DISABLE will return
- * -#BPMP_EACCES.
+ * #MRQ_CLK command #CMD_CLK_ENABLE or #MRQ_CLK command #CMD_CLK_DISABLE
+ * will return -#BPMP_EACCES.
*/
#define BPMP_CLK_STATE_CHANGE_DENIED (1U << 31)
+/**
+ * Size of the cmd_clk_get_all_info_response::name -array in number
+ * of elements.
+ */
#define MRQ_CLK_NAME_MAXLEN 40U
+
+/**
+ * @brief Maximum number of elements in parent_id arrays of clock info responses.
+ */
#define MRQ_CLK_MAX_PARENTS 16U
-/** @private */
+/**
+ * @brief Request payload for #MRQ_CLK sub-command #CMD_CLK_GET_RATE
+ *
+ * This structure is an empty placeholder for future expansion of this
+ * sub-command.
+ */
struct cmd_clk_get_rate_request {
BPMP_ABI_EMPTY
} BPMP_ABI_PACKED;
+/**
+ * @brief Response payload for #MRQ_CLK sub-command #CMD_CLK_GET_RATE
+ */
struct cmd_clk_get_rate_response {
+ /**
+ * Current rate of the given clock in Hz if mrq_response::err is 0 to
+ * indicate successful #CMD_CLK_GET_RATE -request.
+ */
int64_t rate;
} BPMP_ABI_PACKED;
+/**
+ * @brief Request payload for #MRQ_CLK sub-command #CMD_CLK_SET_RATE
+ */
struct cmd_clk_set_rate_request {
+ /** Unused / reserved field. */
int32_t unused;
+
+ /** Requested rate of the clock in Hz. */
int64_t rate;
} BPMP_ABI_PACKED;
+/**
+ * @brief Response payload for #MRQ_CLK sub-command #CMD_CLK_SET_RATE
+ */
struct cmd_clk_set_rate_response {
+ /**
+ * If request was successful (mrq_response::err is 0), set to the new
+ * rate of the given clock in Hz.
+ */
int64_t rate;
} BPMP_ABI_PACKED;
+/**
+ * @brief Request payload for #MRQ_CLK sub-command #CMD_CLK_ROUND_RATE
+ */
struct cmd_clk_round_rate_request {
+ /** Unused / reserved field. */
int32_t unused;
+
+ /** Target rate for the clock */
int64_t rate;
} BPMP_ABI_PACKED;
+/**
+ * @brief Response payload for #MRQ_CLK sub-command #CMD_CLK_ROUND_RATE
+ */
struct cmd_clk_round_rate_response {
+ /**
+ * The attainable rate if request was successful
+ * (mrq_response::err is 0).
+ */
int64_t rate;
} BPMP_ABI_PACKED;
-/** @private */
+/**
+ * @brief Request payload for #MRQ_CLK sub-command #CMD_CLK_GET_PARENT
+ *
+ * This structure is an empty placeholder for future expansion of this
+ * sub-command.
+ */
struct cmd_clk_get_parent_request {
BPMP_ABI_EMPTY
} BPMP_ABI_PACKED;
+/**
+ * @brief Response payload for #MRQ_CLK sub-command #CMD_CLK_GET_PARENT
+ */
struct cmd_clk_get_parent_response {
+ /**
+ * The clock identifier of the parent clock if request was successful
+ * (mrq_response::err is 0).
+ */
uint32_t parent_id;
} BPMP_ABI_PACKED;
+/**
+ * @brief Request payload for #MRQ_CLK sub-command #CMD_CLK_SET_PARENT
+ */
struct cmd_clk_set_parent_request {
+ /**
+ * The clock identifier of the new parent clock.
+ */
uint32_t parent_id;
} BPMP_ABI_PACKED;
+/**
+ * @brief Response payload for #MRQ_CLK sub-command #CMD_CLK_SET_PARENT
+ */
struct cmd_clk_set_parent_response {
+ /**
+ * The clock identifier of the new parent clock if request was
+ * successful (mrq_response::err is 0).
+ */
uint32_t parent_id;
} BPMP_ABI_PACKED;
-/** @private */
+/**
+ * @brief Request payload for #CMD_CLK_IS_ENABLED -sub-command
+ *
+ * This structure is an empty placeholder for future expansion of this
+ * sub-command.
+ */
struct cmd_clk_is_enabled_request {
BPMP_ABI_EMPTY
} BPMP_ABI_PACKED;
/**
- * @brief Response data to #MRQ_CLK sub-command CMD_CLK_IS_ENABLED
+ * @brief Response payload for #MRQ_CLK sub-command #CMD_CLK_IS_ENABLED
*/
struct cmd_clk_is_enabled_response {
/**
* @brief The state of the clock that has been successfully
- * requested with CMD_CLK_ENABLE or CMD_CLK_DISABLE by the
+ * requested with #CMD_CLK_ENABLE or #CMD_CLK_DISABLE by the
* master invoking the command earlier.
*
* The state may not reflect the physical state of the clock
* if there are some other masters requesting it to be
- * enabled.
+ * enabled. Valid values:
*
- * Value 0 is disabled, all other values indicate enabled.
+ * * Value 0: The clock is disabled,
+ * * Value 1: The clock is enabled.
*/
int32_t state;
} BPMP_ABI_PACKED;
-/** @private */
+/**
+ * @brief Request payload for #MRQ_CLK sub-command #CMD_CLK_ENABLE
+ *
+ * This structure is an empty placeholder for future expansion of this
+ * sub-command.
+ */
struct cmd_clk_enable_request {
BPMP_ABI_EMPTY
} BPMP_ABI_PACKED;
-/** @private */
+/**
+ * @brief Response payload for #MRQ_CLK sub-command #CMD_CLK_ENABLE
+ *
+ * This structure is an empty placeholder for future expansion of this
+ * sub-command.
+ */
struct cmd_clk_enable_response {
BPMP_ABI_EMPTY
} BPMP_ABI_PACKED;
-/** @private */
+/**
+ * @brief Request payload for #MRQ_CLK sub-command #CMD_CLK_DISABLE
+ *
+ * This structure is an empty placeholder for future expansion of this
+ * sub-command.
+ */
struct cmd_clk_disable_request {
BPMP_ABI_EMPTY
} BPMP_ABI_PACKED;
-/** @private */
+/**
+ * @brief Response payload for #MRQ_CLK sub-command #CMD_CLK_DISABLE
+ *
+ * This structure is an empty placeholder for future expansion of this
+ * sub-command.
+ */
struct cmd_clk_disable_response {
BPMP_ABI_EMPTY
} BPMP_ABI_PACKED;
-/** @cond DEPRECATED */
-/** @private */
-struct cmd_clk_properties_request {
- BPMP_ABI_EMPTY
-} BPMP_ABI_PACKED;
-
-/** @todo flags need to be spelled out here */
-struct cmd_clk_properties_response {
- uint32_t flags;
-} BPMP_ABI_PACKED;
-
-/** @private */
-struct cmd_clk_possible_parents_request {
- BPMP_ABI_EMPTY
-} BPMP_ABI_PACKED;
-
-struct cmd_clk_possible_parents_response {
- uint8_t num_parents;
- uint8_t reserved[3];
- uint32_t parent_id[MRQ_CLK_MAX_PARENTS];
-} BPMP_ABI_PACKED;
-
-/** @private */
-struct cmd_clk_num_possible_parents_request {
- BPMP_ABI_EMPTY
-} BPMP_ABI_PACKED;
-
-struct cmd_clk_num_possible_parents_response {
- uint8_t num_parents;
-} BPMP_ABI_PACKED;
-
-struct cmd_clk_get_possible_parent_request {
- uint8_t parent_idx;
-} BPMP_ABI_PACKED;
-
-struct cmd_clk_get_possible_parent_response {
- uint32_t parent_id;
-} BPMP_ABI_PACKED;
-/** @endcond DEPRECATED */
-
-/** @private */
+/**
+ * @brief Request payload for #MRQ_CLK sub-command #CMD_CLK_GET_ALL_INFO
+ *
+ * This structure is an empty placeholder for future expansion of this
+ * sub-command.
+ */
struct cmd_clk_get_all_info_request {
BPMP_ABI_EMPTY
} BPMP_ABI_PACKED;
+
+/**
+ * @brief Response payload for #MRQ_CLK sub-command #CMD_CLK_GET_ALL_INFO
+ *
+ * The values in the response are only set and valid if request status in
+ * mrq_response::err is 0.
+ */
struct cmd_clk_get_all_info_response {
+ /**
+ * State / informational flags for the clock:
+ *
+ * | Flag bit | Description |
+ * |------------------------|------------------------------------------|
+ * | #BPMP_CLK_IS_ROOT | Clock is a root clock. |
+ * | #BPMP_CLK_HAS_MUX | Clock supports changing of parent clock. |
+ * | #BPMP_CLK_HAS_SET_RATE | Clock supports changing clock rate. |
+ */
uint32_t flags;
+
+ /**
+ * Current parent clock identifier.
+ */
uint32_t parent;
+
+ /**
+ * Array of possible parent clock identifiers.
+ */
uint32_t parents[MRQ_CLK_MAX_PARENTS];
+
+ /**
+ * Number of identifiers in the #parents -array.
+ */
uint8_t num_parents;
+
+ /**
+ * Friendly name of the clock, truncated to fit the array
+ * and null-terminated.
+ */
uint8_t name[MRQ_CLK_NAME_MAXLEN];
} BPMP_ABI_PACKED;
-/** @private */
+
+/**
+ * @brief Request payload for #MRQ_CLK sub-command #CMD_CLK_GET_MAX_CLK_ID
+ *
+ * This structure is an empty placeholder for future expansion of this
+ * sub-command.
+ */
struct cmd_clk_get_max_clk_id_request {
BPMP_ABI_EMPTY
} BPMP_ABI_PACKED;
+/**
+ * @brief Response payload for #MRQ_CLK sub-command #CMD_CLK_GET_MAX_CLK_ID
+ */
struct cmd_clk_get_max_clk_id_response {
+ /** @brief Largest supported clock identifier. */
uint32_t max_id;
} BPMP_ABI_PACKED;
-/** @private */
+/**
+ * @brief Request payload for #MRQ_CLK sub-command #CMD_CLK_GET_FMAX_AT_VMIN
+ *
+ * This structure is an empty placeholder for future expansion of this
+ * sub-command.
+ */
struct cmd_clk_get_fmax_at_vmin_request {
BPMP_ABI_EMPTY
} BPMP_ABI_PACKED;
+/**
+ * @brief Response payload for #MRQ_CLK sub-command #CMD_CLK_GET_FMAX_AT_VMIN
+ */
struct cmd_clk_get_fmax_at_vmin_response {
int64_t rate;
} BPMP_ABI_PACKED;
@@ -1308,38 +1761,26 @@ struct cmd_clk_get_fmax_at_vmin_response {
* require no additional data. Others have a sub-command specific
* payload
*
- * |sub-command |payload |
- * |----------------------------|-----------------------|
- * |CMD_CLK_GET_RATE |- |
- * |CMD_CLK_SET_RATE |clk_set_rate |
- * |CMD_CLK_ROUND_RATE |clk_round_rate |
- * |CMD_CLK_GET_PARENT |- |
- * |CMD_CLK_SET_PARENT |clk_set_parent |
- * |CMD_CLK_IS_ENABLED |- |
- * |CMD_CLK_ENABLE |- |
- * |CMD_CLK_DISABLE |- |
- * |CMD_CLK_GET_ALL_INFO |- |
- * |CMD_CLK_GET_MAX_CLK_ID |- |
- * |CMD_CLK_GET_FMAX_AT_VMIN |-
- * |
- *
+ * |Sub-command |Payload |
+ * |----------------------------|-----------------------------|
+ * |#CMD_CLK_GET_RATE |- |
+ * |#CMD_CLK_SET_RATE |#cmd_clk_set_rate_request |
+ * |#CMD_CLK_ROUND_RATE |#cmd_clk_round_rate_request |
+ * |#CMD_CLK_GET_PARENT |- |
+ * |#CMD_CLK_SET_PARENT |#cmd_clk_set_parent_request |
+ * |#CMD_CLK_IS_ENABLED |- |
+ * |#CMD_CLK_ENABLE |- |
+ * |#CMD_CLK_DISABLE |- |
+ * |#CMD_CLK_GET_ALL_INFO |- |
+ * |#CMD_CLK_GET_MAX_CLK_ID |- |
+ * |#CMD_CLK_GET_FMAX_AT_VMIN |- |
*/
-/** @cond DEPRECATED
- *
- * Older versions of firmware also supported following sub-commands:
- * |CMD_CLK_PROPERTIES |- |
- * |CMD_CLK_POSSIBLE_PARENTS |- |
- * |CMD_CLK_NUM_POSSIBLE_PARENTS|- |
- * |CMD_CLK_GET_POSSIBLE_PARENT |clk_get_possible_parent|
- * |CMD_CLK_RESET_REFCOUNTS |- |
- *
- * @endcond DEPRECATED */
-
struct mrq_clk_request {
/** @brief Sub-command and clock id concatenated to 32-bit word.
- * - bits[31..24] is the sub-cmd.
- * - bits[23..0] is the clock id
+ *
+ * - bits[31..24] is the sub-command ID from @ref mrq_clk_commands.
+ * - bits[23..0] is the clock identifier from @ref bpmp_clock_ids.
*/
uint32_t cmd_and_id;
@@ -1357,15 +1798,6 @@ struct mrq_clk_request {
struct cmd_clk_disable_request clk_disable;
/** @private */
struct cmd_clk_is_enabled_request clk_is_enabled;
- /** @cond DEPRECATED */
- /** @private */
- struct cmd_clk_properties_request clk_properties;
- /** @private */
- struct cmd_clk_possible_parents_request clk_possible_parents;
- /** @private */
- struct cmd_clk_num_possible_parents_request clk_num_possible_parents;
- struct cmd_clk_get_possible_parent_request clk_get_possible_parent;
- /** @endcond DEPRECATED */
/** @private */
struct cmd_clk_get_all_info_request clk_get_all_info;
/** @private */
@@ -1381,35 +1813,24 @@ struct mrq_clk_request {
*
* Each sub-command supported by @ref mrq_clk_request may return
* sub-command-specific data. Some do and some do not as indicated in
- * the following table
+ * the following table:
*
- * |sub-command |payload |
- * |----------------------------|------------------------|
- * |CMD_CLK_GET_RATE |clk_get_rate |
- * |CMD_CLK_SET_RATE |clk_set_rate |
- * |CMD_CLK_ROUND_RATE |clk_round_rate |
- * |CMD_CLK_GET_PARENT |clk_get_parent |
- * |CMD_CLK_SET_PARENT |clk_set_parent |
- * |CMD_CLK_IS_ENABLED |clk_is_enabled |
- * |CMD_CLK_ENABLE |- |
- * |CMD_CLK_DISABLE |- |
- * |CMD_CLK_GET_ALL_INFO |clk_get_all_info |
- * |CMD_CLK_GET_MAX_CLK_ID |clk_get_max_id |
- * |CMD_CLK_GET_FMAX_AT_VMIN |clk_get_fmax_at_vmin |
+ * |Sub-command |Payload |
+ * |----------------------------|-----------------------------------|
+ * |#CMD_CLK_GET_RATE |#cmd_clk_get_rate_response |
+ * |#CMD_CLK_SET_RATE |#cmd_clk_set_rate_response |
+ * |#CMD_CLK_ROUND_RATE |#cmd_clk_round_rate_response |
+ * |#CMD_CLK_GET_PARENT |#cmd_clk_get_parent_response |
+ * |#CMD_CLK_SET_PARENT |#cmd_clk_set_parent_response |
+ * |#CMD_CLK_IS_ENABLED |#cmd_clk_is_enabled_response |
+ * |#CMD_CLK_ENABLE |- |
+ * |#CMD_CLK_DISABLE |- |
+ * |#CMD_CLK_GET_ALL_INFO |#cmd_clk_get_all_info_response |
+ * |#CMD_CLK_GET_MAX_CLK_ID |#cmd_clk_get_max_clk_id_response |
+ * |#CMD_CLK_GET_FMAX_AT_VMIN |#cmd_clk_get_fmax_at_vmin_response |
*
*/
-/** @cond DEPRECATED
- *
- * Older versions of firmware also supported following sub-commands:
- * |CMD_CLK_PROPERTIES |clk_properties |
- * |CMD_CLK_POSSIBLE_PARENTS |clk_possible_parents |
- * |CMD_CLK_NUM_POSSIBLE_PARENTS|clk_num_possible_parents|
- * |CMD_CLK_GET_POSSIBLE_PARENT |clk_get_possible_parents|
- * |CMD_CLK_RESET_REFCOUNTS |- |
- *
- * @endcond DEPRECATED */
-
struct mrq_clk_response {
union {
struct cmd_clk_get_rate_response clk_get_rate;
@@ -1422,12 +1843,6 @@ struct mrq_clk_response {
/** @private */
struct cmd_clk_disable_response clk_disable;
struct cmd_clk_is_enabled_response clk_is_enabled;
- /** @cond DEPRECATED */
- struct cmd_clk_properties_response clk_properties;
- struct cmd_clk_possible_parents_response clk_possible_parents;
- struct cmd_clk_num_possible_parents_response clk_num_possible_parents;
- struct cmd_clk_get_possible_parent_response clk_get_possible_parent;
- /** @endcond DEPRECATED */
struct cmd_clk_get_all_info_response clk_get_all_info;
struct cmd_clk_get_max_clk_id_response clk_get_max_clk_id;
struct cmd_clk_get_fmax_at_vmin_response clk_get_fmax_at_vmin;
@@ -1441,7 +1856,6 @@ struct mrq_clk_response {
* @def MRQ_QUERY_ABI
* @brief Check if an MRQ is implemented
*
- * * Platforms: All
* * Initiators: Any
* * Targets: Any except DMCE
* * Request Payload: @ref mrq_query_abi_request
@@ -1450,7 +1864,7 @@ struct mrq_clk_response {
/**
* @ingroup ABI_info
- * @brief Request with MRQ_QUERY_ABI
+ * @brief Request with #MRQ_QUERY_ABI
*
* Used by #MRQ_QUERY_ABI call to check if MRQ code #mrq is supported
* by the recipient.
@@ -1468,7 +1882,11 @@ struct mrq_query_abi_request {
* successful, not that the MRQ itself is supported!
*/
struct mrq_query_abi_response {
- /** @brief 0 if queried MRQ is supported. Else, -#BPMP_ENODEV */
+ /**
+ * This response field is set to:
+ * - 0 if queried MRQ is supported, or
+ * - -#BPMP_ENODEV if queried MRQ is not supported
+ */
int32_t status;
} BPMP_ABI_PACKED;
@@ -1476,9 +1894,7 @@ struct mrq_query_abi_response {
*
* @ingroup MRQ_Codes
* @def MRQ_PG
- * @brief Control power-gating state of a partition. In contrast to
- * MRQ_PG_UPDATE_STATE, operations that change the power partition
- * state are NOT reference counted
+ * @brief Control power-gating state of a partition.
*
* @cond (bpmp_t194 || bpmp_t186)
* @note On T194 and earlier BPMP-FW forcefully turns off some partitions as
@@ -1486,9 +1902,8 @@ struct mrq_query_abi_response {
* Therefore, it is recommended to power off all domains via MRQ_PG prior to SC7
* entry.
* See @ref bpmp_pdomain_ids for further detail.
- * @endcond (bpmp_t194 || bpmp_t186)
+ * @endcond
*
- * * Platforms: T186, T194
* * Initiators: Any
* * Targets: BPMP
* * Request Payload: @ref mrq_pg_request
@@ -1497,6 +1912,10 @@ struct mrq_query_abi_response {
* @addtogroup Powergating
* @{
*/
+
+/**
+ * @brief Sub-command identifiers for #MRQ_PG -command.
+ */
enum mrq_pg_cmd {
/**
* @brief Check whether the BPMP driver supports the specified
@@ -1512,9 +1931,14 @@ enum mrq_pg_cmd {
* possible values for power domains are defined in enum
* pg_states
*
- * mrq_response:err is
- * 0: Success
- * -#BPMP_EINVAL: Invalid request parameters
+ * mrq_response:err for this sub-command is defined as:
+ *
+ * | Value | Description |
+ * | -------------- | ------------------------------------------------------------------------ |
+ * | 0 | Request was successful. |
+ * | -#BPMP_EINVAL | Invalid request parameters were provided. |
+ * | -#BPMP_EACCES | Permission denied or always-off partition was attempted to be turned on. |
+ * | Any other <0 | Internal error while performing the operation. |
*/
CMD_PG_SET_STATE = 1,
@@ -1523,18 +1947,26 @@ enum mrq_pg_cmd {
* possible values for power domains are defined in enum
* pg_states
*
- * mrq_response:err is
- * 0: Success
- * -#BPMP_EINVAL: Invalid request parameters
+ * mrq_response:err for this sub-command is defined as:
+ *
+ * | Value | Description |
+ * | -------------- | ---------------------------------------------- |
+ * | 0 | Request was successful. |
+ * | -#BPMP_EINVAL | Invalid request parameters were provided. |
+ * | Any other <0 | Internal error while performing the operation. |
*/
CMD_PG_GET_STATE = 2,
/**
* @brief Get the name string of specified power domain id.
*
- * mrq_response:err is
- * 0: Success
- * -#BPMP_EINVAL: Invalid request parameters
+ * mrq_response:err for this sub-command is defined as:
+ *
+ * | Value | Description |
+ * | -------------- | ---------------------------------------------- |
+ * | 0 | Request was successful. |
+ * | -#BPMP_EINVAL | Invalid request parameters were provided. |
+ * | Any other <0 | Internal error while performing the operation. |
*/
CMD_PG_GET_NAME = 3,
@@ -1543,20 +1975,29 @@ enum mrq_pg_cmd {
* @brief Get the highest power domain id in the system. Not
* all IDs between 0 and max_id are valid IDs.
*
- * mrq_response:err is
- * 0: Success
- * -#BPMP_EINVAL: Invalid request parameters
+ * mrq_response:err for this sub-command is defined as:
+ *
+ * | Value | Description |
+ * | -------------- | ---------------------------------------------- |
+ * | 0 | Request was successful. |
+ * | -#BPMP_EINVAL | Invalid request parameters were provided. |
+ * | Any other <0 | Internal error while performing the operation. |
*/
CMD_PG_GET_MAX_ID = 4,
};
#define MRQ_PG_NAME_MAXLEN 40
+/**
+ * @brief State value for the cmd_pg_set_state_request::state -field.
+ */
enum pg_states {
/** @brief Power domain is OFF */
PG_STATE_OFF = 0,
/** @brief Power domain is ON */
PG_STATE_ON = 1,
+
+ /** @cond bpmp_t186 */
/**
* @brief a legacy state where power domain and the clock
* associated to the domain are ON.
@@ -1564,40 +2005,51 @@ enum pg_states {
* deprecated.
*/
PG_STATE_RUNNING = 2,
+ /** @endcond */
};
struct cmd_pg_query_abi_request {
- /** @ref mrq_pg_cmd */
+ /** #MRQ_PG sub-command identifier from @ref mrq_pg_cmd */
uint32_t type;
} BPMP_ABI_PACKED;
struct cmd_pg_set_state_request {
- /** @ref pg_states */
+ /** One of the state values from @ref pg_states */
uint32_t state;
} BPMP_ABI_PACKED;
/**
- * @brief Response data to #MRQ_PG sub command #CMD_PG_GET_STATE
+ * @brief Response payload for the #MRQ_PG sub-command #CMD_PG_GET_STATE
*/
struct cmd_pg_get_state_response {
/**
* @brief The state of the power partition that has been
- * succesfuly requested by the master earlier using #MRQ_PG
+ * successfully requested by the master earlier using #MRQ_PG
* command #CMD_PG_SET_STATE.
*
* The state may not reflect the physical state of the power
* partition if there are some other masters requesting it to
* be enabled.
*
- * See @ref pg_states for possible values
+ * See @ref pg_states for possible values.
*/
uint32_t state;
} BPMP_ABI_PACKED;
+/**
+ * @brief Response payload for the #MRQ_PG sub-command #CMD_PG_GET_NAME
+ */
struct cmd_pg_get_name_response {
+ /**
+ * @brief On successful response contains the null-terminated
+ * friendly name of the requested power-domain.
+ */
uint8_t name[MRQ_PG_NAME_MAXLEN];
} BPMP_ABI_PACKED;
+/**
+ * @brief Response payload for the #MRQ_PG sub-command #CMD_PG_GET_MAX_ID
+ */
struct cmd_pg_get_max_id_response {
uint32_t max_id;
} BPMP_ABI_PACKED;
@@ -1606,22 +2058,28 @@ struct cmd_pg_get_max_id_response {
* @brief Request with #MRQ_PG
*
* Used by the sender of an #MRQ_PG message to control power
- * partitions. The pg_request is split into several sub-commands. Some
- * sub-commands require no additional data. Others have a sub-command
- * specific payload
+ * partitions. The expected payload depends on the sub-command identifier.
+ * Some sub-commands require no additional data while others have a sub-command
+ * specific payload:
*
- * |sub-command |payload |
- * |----------------------------|-----------------------|
- * |CMD_PG_QUERY_ABI | query_abi |
- * |CMD_PG_SET_STATE | set_state |
- * |CMD_PG_GET_STATE | - |
- * |CMD_PG_GET_NAME | - |
- * |CMD_PG_GET_MAX_ID | - |
+ * |Sub-command |Payload |
+ * |----------------------------|---------------------------|
+ * |#CMD_PG_QUERY_ABI | #cmd_pg_query_abi_request |
+ * |#CMD_PG_SET_STATE | #cmd_pg_set_state_request |
+ * |#CMD_PG_GET_STATE | - |
+ * |#CMD_PG_GET_NAME | - |
+ * |#CMD_PG_GET_MAX_ID | - |
*
*/
struct mrq_pg_request {
+ /** @brief Sub-command identifier from @ref mrq_pg_cmd. */
uint32_t cmd;
+
+ /**
+ * @brief Power-domain identifier
+ */
uint32_t id;
+
union {
struct cmd_pg_query_abi_request query_abi;
struct cmd_pg_set_state_request set_state;
@@ -1629,19 +2087,18 @@ struct mrq_pg_request {
} BPMP_ABI_PACKED;
/**
- * @brief Response to MRQ_PG
+ * @brief Response to #MRQ_PG
*
- * Each sub-command supported by @ref mrq_pg_request may return
- * sub-command-specific data. Some do and some do not as indicated in
- * the following table
+ * Some of the #MRQ_PG sub-commands return a sub-command -specific payload
+ * as specified in the following table:
*
- * |sub-command |payload |
- * |----------------------------|-----------------------|
- * |CMD_PG_QUERY_ABI | - |
- * |CMD_PG_SET_STATE | - |
- * |CMD_PG_GET_STATE | get_state |
- * |CMD_PG_GET_NAME | get_name |
- * |CMD_PG_GET_MAX_ID | get_max_id |
+ * |Sub-command |Payload |
+ * |--------------------|------------------------------|
+ * |#CMD_PG_QUERY_ABI | - |
+ * |#CMD_PG_SET_STATE | - |
+ * |#CMD_PG_GET_STATE | #cmd_pg_get_state_response |
+ * |#CMD_PG_GET_NAME | #cmd_pg_get_name_response |
+ * |#CMD_PG_GET_MAX_ID | #cmd_pg_get_max_id_response |
*/
struct mrq_pg_response {
union {
@@ -1658,11 +2115,10 @@ struct mrq_pg_response {
* @def MRQ_THERMAL
* @brief Interact with BPMP thermal framework
*
- * * Platforms: T186, T194
* * Initiators: Any
* * Targets: Any
- * * Request Payload: TODO
- * * Response Payload: TODO
+ * * Request Payload: #mrq_thermal_host_to_bpmp_request
+ * * Response Payload: #mrq_thermal_bpmp_to_host_response
*
* @addtogroup Thermal
*
@@ -1686,10 +2142,14 @@ struct mrq_pg_response {
* payload of @ref mrq_thermal_bpmp_to_host_request.
* @{
*/
+
+/**
+ * @brief Sub-command identifiers for Host->BPMP #MRQ_THERMAL -command.
+ */
enum mrq_thermal_host_to_bpmp_cmd {
/**
- * @brief Check whether the BPMP driver supports the specified
- * request type.
+ * @brief Check whether BPMP-FW supports the specified
+ * #MRQ_THERMAL sub-command.
*
* Host needs to supply request parameters.
*
@@ -1703,31 +2163,44 @@ enum mrq_thermal_host_to_bpmp_cmd {
*
* Host needs to supply request parameters.
*
- * mrq_response::err is
- * * 0: Temperature query succeeded.
- * * -#BPMP_EINVAL: Invalid request parameters.
- * * -#BPMP_ENOENT: No driver registered for thermal zone..
- * * -#BPMP_EFAULT: Problem reading temperature measurement.
+ * mrq_response::err value for this sub-command is:
+ *
+ * | Value | Description |
+ * | -------------- | ----------------------------------------- |
+ * | 0 | Temperature query succeeded. |
+ * | -#BPMP_EINVAL | Invalid request parameters. |
+ * | -#BPMP_ENOENT | No driver registered for thermal zone. |
+ * | -#BPMP_EFAULT | Problem reading temperature measurement. |
*/
CMD_THERMAL_GET_TEMP = 1,
/**
+ * @cond (!bpmp_safe && !bpmp_t264)
* @brief Enable or disable and set the lower and upper
* thermal limits for a thermal trip point. Each zone has
* one trip point.
*
* Host needs to supply request parameters. Once the
* temperature hits a trip point, the BPMP will send a message
- * to the CPU having MRQ=MRQ_THERMAL and
- * type=CMD_THERMAL_HOST_TRIP_REACHED
+ * to the CPU having MRQ command identifier equal to #MRQ_THERMAL and
+ * sub-command identifier equal to #CMD_THERMAL_HOST_TRIP_REACHED.
*
- * mrq_response::err is
- * * 0: Trip successfully set.
- * * -#BPMP_EINVAL: Invalid request parameters.
- * * -#BPMP_ENOENT: No driver registered for thermal zone.
- * * -#BPMP_EFAULT: Problem setting trip point.
+ * If #CMD_THERMAL_SET_TRIP -sub-command is issued for a
+ * thermal zone that is currently power gated and unable to
+ * report temperature, a temperature of -256C is used as
+ * temperature for evaluation of the trip.
+ *
+ * mrq_response::err for this sub-command is defined as:
+ *
+ * | Value | Description |
+ * | --------------- | -------------------------------------- |
+ * | 0 | Trip successfully set. |
+ * | -#BPMP_EINVAL | Invalid request parameters. |
+ * | -#BPMP_ENOENT | No driver registered for thermal zone. |
+ * | -#BPMP_EFAULT | Problem setting trip point. |
*/
CMD_THERMAL_SET_TRIP = 2,
+ /** @endcond */
/**
* @brief Get the number of supported thermal zones.
@@ -1739,135 +2212,153 @@ enum mrq_thermal_host_to_bpmp_cmd {
CMD_THERMAL_GET_NUM_ZONES = 3,
/**
- * @brief Get the thermtrip of the specified zone.
+ * @brief Get the thermal trip value of the specified zone.
*
* Host needs to supply request parameters.
*
- * mrq_response::err is
- * * 0: Valid zone information returned.
- * * -#BPMP_EINVAL: Invalid request parameters.
- * * -#BPMP_ENOENT: No driver registered for thermal zone.
- * * -#BPMP_ERANGE if thermtrip is invalid or disabled.
- * * -#BPMP_EFAULT: Problem reading zone information.
+ * mrq_response::err for this sub-command is defined as:
+ *
+ * | Value | Description |
+ * | --------------- | -------------------------------------- |
+ * | 0 | Valid zone information returned. |
+ * | -#BPMP_EINVAL | Invalid request parameters. |
+ * | -#BPMP_ENOENT | No driver registered for thermal zone. |
+ * | -#BPMP_ERANGE | Thermal trip is invalid or disabled. |
+ * | -#BPMP_EFAULT | Problem reading zone information. |
*/
CMD_THERMAL_GET_THERMTRIP = 4,
- /** @brief: number of supported host-to-bpmp commands. May
- * increase in future
+ /**
+ * @brief Number of supported host-to-bpmp commands.
*/
CMD_THERMAL_HOST_TO_BPMP_NUM
};
+/**
+ * @brief Sub-command identifiers for BPMP->host #MRQ_THERMAL -command
+ */
enum mrq_thermal_bpmp_to_host_cmd {
/**
* @brief Indication that the temperature for a zone has
- * exceeded the range indicated in the thermal trip point
- * for the zone.
+ * exceeded the range indicated in the thermal trip point
+ * for the zone.
*
- * BPMP needs to supply request parameters. Host only needs to
+ * BPMP-FW needs to supply request parameters. Host only needs to
* acknowledge.
*/
CMD_THERMAL_HOST_TRIP_REACHED = 100,
- /** @brief: number of supported bpmp-to-host commands. May
- * increase in future
+ /**
+ * @brief: Number of supported bpmp-to-host commands. May
+ * increase in future.
*/
CMD_THERMAL_BPMP_TO_HOST_NUM
};
-/*
- * Host->BPMP request data for request type CMD_THERMAL_QUERY_ABI
- *
- * zone: Request type for which to check existence.
+/**
+ * Host->BPMP request payload for the #CMD_THERMAL_QUERY_ABI sub-command
*/
struct cmd_thermal_query_abi_request {
+ /**
+ * Request type for which to check whether supported by BPMP-FW.
+ *
+ * Valid identifiers are available at #mrq_thermal_host_to_bpmp_cmd
+ */
uint32_t type;
} BPMP_ABI_PACKED;
-/*
- * Host->BPMP request data for request type CMD_THERMAL_GET_TEMP
- *
- * zone: Number of thermal zone.
+/**
+ * Host->BPMP request payload for the #CMD_THERMAL_GET_TEMP sub-command
*/
struct cmd_thermal_get_temp_request {
+ /** Thermal zone identifier from @ref bpmp_thermal_ids. */
uint32_t zone;
} BPMP_ABI_PACKED;
-/*
- * BPMP->Host reply data for request CMD_THERMAL_GET_TEMP
+/**
+ * BPMP->Host response payload for the #CMD_THERMAL_GET_TEMP sub-command.
+ *
+ * mrq_response::err is defined as:
*
- * error: 0 if request succeeded.
- * -BPMP_EINVAL if request parameters were invalid.
- * -BPMP_ENOENT if no driver was registered for the specified thermal zone.
- * -BPMP_EFAULT for other thermal zone driver errors.
- * temp: Current temperature in millicelsius.
+ * | Value | Description |
+ * | ------------- | -------------------------------------------------------- |
+ * | 0 | Request succeeded. |
+ * | -#BPMP_EINVAL | Request parameters were invalid. |
+ * | -#BPMP_ENOENT | No driver was registered for the specified thermal zone. |
+ * | -#BPMP_EFAULT | For other BPMP-FW internal thermal zone driver errors. |
*/
struct cmd_thermal_get_temp_response {
+ /** @brief Current temperature in millicelsius. */
int32_t temp;
} BPMP_ABI_PACKED;
-/*
- * Host->BPMP request data for request type CMD_THERMAL_SET_TRIP
+/**
+ * @cond (!bpmp_safe && !bpmp_t264)
*
- * zone: Number of thermal zone.
- * low: Temperature of lower trip point in millicelsius
- * high: Temperature of upper trip point in millicelsius
- * enabled: 1 to enable trip point, 0 to disable trip point
+ * Host->BPMP request payload for the #CMD_THERMAL_SET_TRIP sub-command.
*/
struct cmd_thermal_set_trip_request {
+ /** @brief Thermal zone identifier from @ref bpmp_thermal_ids. */
uint32_t zone;
+ /** @brief Temperature of lower trip point in millicelsius */
int32_t low;
+ /** @brief Temperature of upper trip point in millicelsius */
int32_t high;
+ /** 1 to enable trip point, 0 to disable trip point */
uint32_t enabled;
} BPMP_ABI_PACKED;
-/*
- * BPMP->Host request data for request type CMD_THERMAL_HOST_TRIP_REACHED
- *
- * zone: Number of thermal zone where trip point was reached.
+/**
+ * BPMP->Host request payload for the #CMD_THERMAL_HOST_TRIP_REACHED sub-command.
*/
struct cmd_thermal_host_trip_reached_request {
+ /**
+ * @brief ID of the thermal zone where trip point was reached,
+ * from @ref bpmp_thermal_ids.
+ */
uint32_t zone;
} BPMP_ABI_PACKED;
+/** @endcond */
-/*
- * BPMP->Host reply data for request type CMD_THERMAL_GET_NUM_ZONES
- *
- * num: Number of supported thermal zones. The thermal zones are indexed
- * starting from zero.
+/**
+ * BPMP->Host response payload for the #CMD_THERMAL_GET_NUM_ZONES sub-command.
*/
struct cmd_thermal_get_num_zones_response {
+ /**
+ * @brief Number of supported thermal zones.
+ *
+ * The thermal zones are indexed starting from zero.
+ */
uint32_t num;
} BPMP_ABI_PACKED;
-/*
- * Host->BPMP request data for request type CMD_THERMAL_GET_THERMTRIP
- *
- * zone: Number of thermal zone.
+/**
+ * Host->BPMP request payload for the #CMD_THERMAL_GET_THERMTRIP sub-command.
*/
struct cmd_thermal_get_thermtrip_request {
+ /** @brief Thermal zone identifier from @ref bpmp_thermal_ids. */
uint32_t zone;
} BPMP_ABI_PACKED;
-/*
- * BPMP->Host reply data for request CMD_THERMAL_GET_THERMTRIP
- *
- * thermtrip: HW shutdown temperature in millicelsius.
+/**
+ * BPMP->Host response payload for the #CMD_THERMAL_GET_THERMTRIP sub-command.
*/
struct cmd_thermal_get_thermtrip_response {
+ /** @brief HW shutdown temperature in millicelsius. */
int32_t thermtrip;
} BPMP_ABI_PACKED;
-/*
- * Host->BPMP request data.
- *
- * Reply type is union mrq_thermal_bpmp_to_host_response.
+/**
+ * Host->BPMP #MRQ_THERMAL request payload.
*
- * type: Type of request. Values listed in enum mrq_thermal_type.
- * data: Request type specific parameters.
+ * Response payload type is #mrq_thermal_bpmp_to_host_response.
*/
struct mrq_thermal_host_to_bpmp_request {
+ /**
+ * Request sub-command identifier from @ref mrq_thermal_host_to_bpmp_cmd.
+ */
uint32_t type;
+
union {
struct cmd_thermal_query_abi_request query_abi;
struct cmd_thermal_get_temp_request get_temp;
@@ -1876,21 +2367,22 @@ struct mrq_thermal_host_to_bpmp_request {
} BPMP_UNION_ANON;
} BPMP_ABI_PACKED;
-/*
- * BPMP->Host request data.
- *
- * type: Type of request. Values listed in enum mrq_thermal_type.
- * data: Request type specific parameters.
+/**
+ * @brief Request payload for the BPMP->Host #MRQ_THERMAL command.
*/
struct mrq_thermal_bpmp_to_host_request {
+ /**
+ * Request sub-command identifier from @ref mrq_thermal_bpmp_to_host_cmd.
+ */
uint32_t type;
+
union {
struct cmd_thermal_host_trip_reached_request host_trip_reached;
} BPMP_UNION_ANON;
} BPMP_ABI_PACKED;
-/*
- * Data in reply to a Host->BPMP request.
+/**
+ * @brief Response payload for the Host->BPMP #MRQ_THERMAL command.
*/
union mrq_thermal_bpmp_to_host_response {
struct cmd_thermal_get_temp_response get_temp;
@@ -1900,13 +2392,11 @@ union mrq_thermal_bpmp_to_host_response {
/** @} Thermal */
-/**
+/** @cond (!bpmp_safe && (bpmp_t234 || bpmp_t238 || bpmp_t264))
* @ingroup MRQ_Codes
* @def MRQ_OC_STATUS
- * @brief Query over current status
+ * @brief Query overcurrent status
*
- * * Platforms: T234
- * @cond bpmp_t234
* * Initiators: CCPLEX
* * Targets: BPMP
* * Request Payload: N/A
@@ -1916,33 +2406,224 @@ union mrq_thermal_bpmp_to_host_response {
* @{
*/
+/**
+ * @brief Size of the mrq_oc_status_response::throt_en and
+ * mrq_oc_status_response::event_cnt -arrays.
+ */
#define OC_STATUS_MAX_SIZE 24U
-/*
- * @brief Response to #MRQ_OC_STATUS
- *
- * throt_en: Value for each OC alarm where zero signifies throttle is
- * disabled, and non-zero throttle is enabled.
- * event_cnt: Total number of OC events for each OC alarm.
+/**
+ * @brief Response payload for the #MRQ_OC_STATUS -command.
*
* mrq_response::err is 0 if the operation was successful and
* -#BPMP_ENODEV otherwise.
*/
struct mrq_oc_status_response {
+ /**
+ * @brief Value for each overcurrent alarm where zero signifies
+ * throttle is disabled, and non-zero throttle is enabled.
+ */
uint8_t throt_en[OC_STATUS_MAX_SIZE];
+
+ /**
+ * @brief Total number of overcurrent events for each overcurrent alarm.
+ */
uint32_t event_cnt[OC_STATUS_MAX_SIZE];
} BPMP_ABI_PACKED;
/** @} OC_status */
-/** @endcond bpmp_t234 */
+/** @endcond */
+
+/** @cond (bpmp_th500 || bpmp_tb500 || bpmp_t238)
+ * @ingroup MRQ_Codes
+ * @def MRQ_THROTTLE
+ * @brief Overcurrent throttling
+ *
+ * * Initiators: CCPLEX
+ * * Targets: BPMP
+ * * Request Payload: @ref mrq_throttle_request
+ * * Response Payload: @ref mrq_throttle_response
+ * @addtogroup Throttle
+ * @{
+ */
+enum mrq_throttle_cmd {
+ /**
+ * @brief Check whether the BPMP-FW supports the specified
+ * #MRQ_THROTTLE sub-command.
+ *
+ * mrq_response::err is 0 if the specified request is
+ * supported and -#BPMP_ENODEV otherwise.
+ */
+ CMD_THROTTLE_QUERY_ABI = 0,
+
+ /**
+ * @cond (bpmp_th500 || bpmp_tb500)
+ * @brief query chipthrot status
+ *
+ * mrq_response:err is defined as:
+ *
+ * | Value | Description |
+ * |----------------|--------------------------------------------------------------|
+ * | 0 | Success |
+ * | -#BPMP_ENODEV | CMD_THROTTLE_GET_CHIPTHROT_STATUS is not supported by BPMP-FW|
+ */
+ CMD_THROTTLE_GET_CHIPTHROT_STATUS = 1,
+ /** @endcond */
+
+ /**
+ * @cond bpmp_t238
+ * @brief program OC throttle configuration
+ *
+ * mrq_response:err is defined as:
+ *
+ * | Value | Description |
+ * |----------------|--------------------------------------------------------------|
+ * | 0 | Success |
+ * | -#BPMP_EINVAL | ID out of range or alarm for this ID not enabled at boot |
+ * | -#BPMP_ENODEV | CMD_THROTTLE_SET_OC_CONFIG is not supported by BPMP-FW |
+ */
+ CMD_THROTTLE_SET_OC_CONFIG = 2,
+ /** @endcond */
+};
+
+/**
+ * @brief Request payload for #MRQ_THROTTLE sub-command #CMD_THROTTLE_QUERY_ABI
+ */
+struct cmd_throttle_query_abi_request {
+ uint32_t cmd; /**< @ref mrq_throttle_cmd */
+} BPMP_ABI_PACKED;
+
+/**
+ * @cond bpmp_th500
+ * @brief Response payload for #MRQ_THROTTLE sub-command
+ * #CMD_THROTTLE_GET_CHIPTHROT_STATUS
+ *
+ * Bit-mask of all h/w throttling actions that have been engaged since
+ * last invocation of this command
+ * Bit 0...11 : HW throttling status of the thermal zones.
+ * Bit 12...23 : Reserved for future thermal zone events.
+ * Bit 24...25 : HW throttling status of the Over current Alarms OC1 & OC2.
+ * Bit 26...31 : Reserved for future Over current alarm events.
+ * Bit 32...63 : Reserved for future use.
+ * @endcond
+ * @cond bpmp_tb500
+ * @brief Response payload for #MRQ_THROTTLE sub-command
+ * #CMD_THROTTLE_GET_CHIPTHROT_STATUS
+ *
+ * Bit-mask of all h/w throttling actions that have been engaged since
+ * last invocation of this command
+ * Bit 0 : HW throttling status of the TB500C_TJ_MAX thermal zone.
+ * Bit 1...63 : Reserved for future use.
+ * @endcond
+ * @cond (bpmp_th500 || bpmp_tb500)
+ */
+struct cmd_throttle_get_chipthrot_status_response {
+ uint64_t status;
+} BPMP_ABI_PACKED;
+/** @endcond */
+
+/**
+ * @cond bpmp_t238
+ * @brief Request payload for #MRQ_THROTTLE sub-command
+ * #CMD_THROTTLE_SET_OC_CONFIG
+ *
+ * Only alarms that have been configured as enabled in BPMP-DTB at boot can
+ * be reconfigured with this MRQ.
+ */
+struct cmd_throttle_set_oc_config_request {
+ /** @brief valid OC alarm ID from @ref bpmp_soctherm_edp_oc_ids */
+ uint32_t id;
+ /** @brief Throttling enable/disable
+ *
+ * Set to 1 to enable throttling, or 0 to disable. Other values are
+ * disallowed.
+ */
+ uint8_t en_throttle;
+} BPMP_ABI_PACKED;
+/** @endcond */
+
+/**
+ * @brief Request payload for the #MRQ_THROTTLE -command
+ *
+ * | Sub-command | Request payload |
+ * |------------------------------------|----------------------------------|
+ * | #CMD_THROTTLE_QUERY_ABI | #cmd_throttle_query_abi_request |
+ *
+ * @cond bpmp_th500
+ * The following additional sub-commands are supported on TH500 platforms:
+ * | Sub-command | Request payload |
+ * |------------------------------------|----------------------------------|
+ * | #CMD_THROTTLE_GET_CHIPTHROT_STATUS | - |
+ * @endcond
+ *
+ * @cond bpmp_tb500
+ * The following additional sub-commands are supported on TB500 platforms:
+ * | Sub-command | Request payload |
+ * |------------------------------------|----------------------------------|
+ * | #CMD_THROTTLE_GET_CHIPTHROT_STATUS | - |
+ * @endcond
+ *
+ * @cond bpmp_t238
+ * The following additional sub-commands are supported on T238 platforms:
+ * | Sub-command | Request payload |
+ * |------------------------------------|-------------------------------------|
+ * | #CMD_THROTTLE_SET_OC_CONFIG | #cmd_throttle_set_oc_config_request |
+ * @endcond
+ */
+struct mrq_throttle_request {
+ uint32_t cmd;
+ union {
+ struct cmd_throttle_query_abi_request throttle_query_abi_req;
+ /** @cond bpmp_t238 */
+ struct cmd_throttle_set_oc_config_request throttle_set_oc_config_req;
+ /** @endcond */
+ } BPMP_UNION_ANON;
+} BPMP_ABI_PACKED;
/**
+ * @brief Response payload for the #MRQ_THROTTLE -command.
+ *
+ * | Sub-command | Response payload |
+ * |------------------------------------|--------------------------------------------|
+ * | #CMD_THROTTLE_QUERY_ABI | - |
+ *
+ * @cond bpmp_th500
+ * The following additional sub-commands are supported on TH500 platforms:
+ * | Sub-command | Response payload |
+ * |------------------------------------|--------------------------------------------|
+ * | #CMD_THROTTLE_GET_CHIPTHROT_STATUS | #cmd_throttle_get_chipthrot_status_response|
+ * @endcond
+ *
+ * @cond bpmp_tb500
+ * The following additional sub-commands are supported on TB500 platforms:
+ * | Sub-command | Response payload |
+ * |------------------------------------|--------------------------------------------|
+ * | #CMD_THROTTLE_GET_CHIPTHROT_STATUS | #cmd_throttle_get_chipthrot_status_response|
+ * @endcond
+ *
+ * @cond bpmp_t238
+ * The following additional sub-commands are supported on T238 platforms:
+ * | Sub-command | Response payload |
+ * |------------------------------------|--------------------------------------------|
+ * | #CMD_THROTTLE_SET_OC_CONFIG | - |
+ * @endcond
+ */
+struct mrq_throttle_response {
+ union {
+ /** @cond (bpmp_th500 || bpmp_tb500) */
+ struct cmd_throttle_get_chipthrot_status_response throttle_get_chipthrot_status_resp;
+ /** @endcond */
+ } BPMP_UNION_ANON;
+} BPMP_ABI_PACKED;
+/** @} Throttle */
+/** @endcond */
+
+
+/** @cond bpmp_t186
* @ingroup MRQ_Codes
* @def MRQ_CPU_VHINT
* @brief Query CPU voltage hint data
*
- * * Platforms: T186
- * @cond bpmp_t186
* * Initiators: CCPLEX
* * Targets: BPMP
* * Request Payload: @ref mrq_cpu_vhint_request
@@ -1995,14 +2676,13 @@ struct cpu_vhint_data {
} BPMP_ABI_PACKED;
/** @} Vhint */
-/** @endcond bpmp_t186 */
+/** @endcond */
/**
* @ingroup MRQ_Codes
* @def MRQ_ABI_RATCHET
* @brief ABI ratchet value query
*
- * * Platforms: T186, T194
* * Initiators: Any
* * Targets: BPMP
* * Request Payload: @ref mrq_abi_ratchet_request
@@ -2014,7 +2694,7 @@ struct cpu_vhint_data {
/**
* @brief An ABI compatibility mechanism
*
- * BPMP_ABI_RATCHET_VALUE may increase for various reasons in a future
+ * #BPMP_ABI_RATCHET_VALUE may increase for various reasons in a future
* revision of this header file.
* 1. That future revision deprecates some MRQ
* 2. That future revision introduces a breaking change to an existing
@@ -2051,11 +2731,11 @@ struct mrq_abi_ratchet_request {
*
* If #ratchet is less than the requester's #BPMP_ABI_RATCHET_VALUE,
* the requster must either interoperate with BPMP according to an ABI
- * header version with BPMP_ABI_RATCHET_VALUE = ratchet or cease
+ * header version with #BPMP_ABI_RATCHET_VALUE = ratchet or cease
* communication with BPMP.
*
* If mrq_response::err is 0 and ratchet is greater than or equal to the
- * requester's BPMP_ABI_RATCHET_VALUE, the requester should continue
+ * requester's #BPMP_ABI_RATCHET_VALUE, the requester should continue
* normal operation.
*/
struct mrq_abi_ratchet_response {
@@ -2070,7 +2750,9 @@ struct mrq_abi_ratchet_response {
* @def MRQ_EMC_DVFS_LATENCY
* @brief Query frequency dependent EMC DVFS latency
*
- * * Platforms: T186, T194, T234
+ * On T264 and onwards, this MRQ service is available only when
+ * BPMP-FW has valid DRAM timing table passed by earlier boot stages.
+ *
* * Initiators: CCPLEX
* * Targets: BPMP
* * Request Payload: N/A
@@ -2094,7 +2776,11 @@ struct emc_dvfs_latency {
* @brief Response to #MRQ_EMC_DVFS_LATENCY
*/
struct mrq_emc_dvfs_latency_response {
- /** @brief The number valid entries in #pairs */
+ /**
+ * @brief The number valid entries in #pairs
+ *
+ * Valid range is [0, #EMC_DVFS_LATENCY_MAX_SIZE]
+ */
uint32_t num_pairs;
/** @brief EMC DVFS node <frequency, latency> information */
struct emc_dvfs_latency pairs[EMC_DVFS_LATENCY_MAX_SIZE];
@@ -2102,13 +2788,11 @@ struct mrq_emc_dvfs_latency_response {
/** @} EMC */
-/**
+/** @cond (bpmp_t234)
* @ingroup MRQ_Codes
* @def MRQ_EMC_DVFS_EMCHUB
* @brief Query EMC HUB frequencies
*
- * * Platforms: T234 onwards
- * @cond (bpmp_t234 || bpmp_t239 || bpmp_th500)
* * Initiators: CCPLEX
* * Targets: BPMP
* * Request Payload: N/A
@@ -2139,15 +2823,13 @@ struct mrq_emc_dvfs_emchub_response {
} BPMP_ABI_PACKED;
/** @} EMC */
-/** @endcond (bpmp_t234 || bpmp_t239 || bpmp_th500) */
+/** @endcond */
-/**
+/** @cond (bpmp_t234)
* @ingroup MRQ_Codes
* @def MRQ_EMC_DISP_RFL
* @brief Set EMC display RFL handshake mode of operations
*
- * * Platforms: T234 onwards
- * @cond (bpmp_t234 || bpmp_t239 || bpmp_th500)
* * Initiators: CCPLEX
* * Targets: BPMP
* * Request Payload: @ref mrq_emc_disp_rfl_request
@@ -2157,6 +2839,9 @@ struct mrq_emc_dvfs_emchub_response {
* @{
*/
+/**
+ * @brief Allowed mode values for the mrq_emc_disp_rfl_request::mode -field.
+ */
enum mrq_emc_disp_rfl_mode {
/** @brief EMC display RFL handshake disabled */
EMC_DISP_RFL_MODE_DISABLED = 0,
@@ -2171,65 +2856,75 @@ enum mrq_emc_disp_rfl_mode {
* Used by the sender of an #MRQ_EMC_DISP_RFL message to
* request the mode of EMC display RFL handshake.
*
- * mrq_response::err is
- * * 0: RFL mode is set successfully
- * * -#BPMP_EINVAL: invalid mode requested
- * * -#BPMP_ENOSYS: RFL handshake is not supported
- * * -#BPMP_EACCES: Permission denied
- * * -#BPMP_ENODEV: if disp rfl mrq is not supported by BPMP-FW
+ * mrq_response::err for this request is defined as:
+ *
+ * | Value | Description |
+ * | -------------- | --------------------------------------------- |
+ * | 0 | RFL mode is set successfully. |
+ * | -#BPMP_EINVAL | Invalid mode requested. |
+ * | -#BPMP_ENOSYS | RFL handshake is not supported. |
+ * | -#BPMP_EACCES | Permission denied. |
+ * | -#BPMP_ENODEV | if disp rfl mrq is not supported by BPMP-FW. |
*/
struct mrq_emc_disp_rfl_request {
- /** @brief EMC display RFL mode (@ref mrq_emc_disp_rfl_mode) */
+ /** @brief EMC display RFL mode from @ref mrq_emc_disp_rfl_mode */
uint32_t mode;
} BPMP_ABI_PACKED;
/** @} EMC */
-/** @endcond (bpmp_t234 || bpmp_t239 || bpmp_th500) */
+/** @endcond */
-/**
+/** @cond (!bpmp_safe && (bpmp_t234 || bpmp_t238))
* @ingroup MRQ_Codes
* @def MRQ_BWMGR
- * @brief bwmgr requests
+ * @brief Bandwidth manager (BWMGR) commands
*
- * * Platforms: T234 onwards
- * @cond (bpmp_t234 || bpmp_t239 || bpmp_th500)
* * Initiators: CCPLEX
* * Targets: BPMP
* * Request Payload: @ref mrq_bwmgr_request
* * Response Payload: @ref mrq_bwmgr_response
*
* @addtogroup BWMGR
- *
* @{
*/
+/**
+ * @brief Sub-command identifiers for #MRQ_BWMGR
+ */
enum mrq_bwmgr_cmd {
/**
- * @brief Check whether the BPMP driver supports the specified
- * request type
+ * @brief Check whether BPMP-FW supports the specified
+ * #MRQ_BWMGR sub-command.
*
- * mrq_response::err is 0 if the specified request is
- * supported and -#BPMP_ENODEV otherwise.
+ * mrq_response::err is defined to be:
+ *
+ * | Value | Description
+ * |----------------|----------------------------
+ * | 0 | Specified sub-command is supported.
+ * | -#BPMP_ENODEV | Specified sub-command is not supported.
*/
CMD_BWMGR_QUERY_ABI = 0,
/**
- * @brief Determine dram rate to satisfy iso/niso bw requests
+ * @brief Determine DRAM rate to satisfy ISO/NISO bandwidth requests
*
- * mrq_response::err is
- * * 0: calc_rate succeeded.
- * * -#BPMP_EINVAL: Invalid request parameters.
- * * -#BPMP_ENOTSUP: Requested bw is not available.
+ * mrq_response::err is defined to be:
+ *
+ * | Value | Description
+ * |----------------|----------------------------
+ * | 0 | Rate calculation succeeded.
+ * | -#BPMP_EINVAL | Invalid request parameters.
+ * | -#BPMP_ENOTSUP | Requested bandwidth is not available.
+ * | <0 | Any other internal error.
*/
CMD_BWMGR_CALC_RATE = 1
};
-/*
- * request data for request type CMD_BWMGR_QUERY_ABI
- *
- * type: Request type for which to check existence.
+/**
+ * @brief Request payload for #MRQ_BWMGR sub-command #CMD_BWMGR_QUERY_ABI
*/
struct cmd_bwmgr_query_abi_request {
+ /** @brief Sub-command identifier from @ref mrq_bwmgr_cmd. */
uint32_t type;
} BPMP_ABI_PACKED;
@@ -2237,47 +2932,56 @@ struct cmd_bwmgr_query_abi_request {
* @brief Used by @ref cmd_bwmgr_calc_rate_request
*/
struct iso_req {
- /* @brief bwmgr client ID @ref bpmp_bwmgr_ids */
+ /** @brief BWMGR client ID from @ref bpmp_bwmgr_ids */
uint32_t id;
- /* @brief bw in kBps requested by client */
+ /** @brief Bandwidth in kBps requested by client */
uint32_t iso_bw;
} BPMP_ABI_PACKED;
+/**
+ * @brief Size of the cmd_bwmgr_calc_rate_request::isobw_reqs -array.
+ */
#define MAX_ISO_CLIENTS 13U
-/*
- * request data for request type CMD_BWMGR_CALC_RATE
+
+/**
+ * @brief Request payload for #MRQ_BWMGR sub-command #CMD_BWMGR_CALC_RATE
*/
struct cmd_bwmgr_calc_rate_request {
- /* @brief total bw in kBps requested by all niso clients */
+ /** @brief Total bandwidth in kBps requested by all NISO clients. */
uint32_t sum_niso_bw;
- /* @brief The number of iso clients */
+ /** @brief The number of ISO client requests in #isobw_reqs -array */
uint32_t num_iso_clients;
- /* @brief iso_req <id, iso_bw> information */
+ /** @brief iso_req <id, iso_bw> information */
struct iso_req isobw_reqs[MAX_ISO_CLIENTS];
} BPMP_ABI_PACKED;
-/*
- * response data for request type CMD_BWMGR_CALC_RATE
- *
- * iso_rate_min: min dram data clk rate in kHz to satisfy all iso bw reqs
- * total_rate_min: min dram data clk rate in kHz to satisfy all bw reqs
+/**
+ * @brief Response payload for #MRQ_BWMGR sub-command #CMD_BWMGR_CALC_RATE
*/
struct cmd_bwmgr_calc_rate_response {
+ /**
+ * @brief Minimum DRAM data clock rate in kHz to satisfy all ISO client
+ * bandwidth requests.
+ */
uint32_t iso_rate_min;
+
+ /**
+ * @brief Minimum DRAM data clock rate in kHz to satisfy all
+ * bandwidth requests.
+ */
uint32_t total_rate_min;
} BPMP_ABI_PACKED;
-/*
- * @brief Request with #MRQ_BWMGR
- *
- *
- * |sub-command |payload |
- * |----------------------------|------------------------------|
- * |CMD_BWMGR_QUERY_ABI | cmd_bwmgr_query_abi_request |
- * |CMD_BWMGR_CALC_RATE | cmd_bwmgr_calc_rate_request |
+/**
+ * @brief Request payload for the #MRQ_BWMGR -command.
*
+ * |Sub-command |Payload |
+ * |----------------------|-----------------------------|
+ * |#CMD_BWMGR_QUERY_ABI |#cmd_bwmgr_query_abi_request |
+ * |#CMD_BWMGR_CALC_RATE |#cmd_bwmgr_calc_rate_request |
*/
struct mrq_bwmgr_request {
+ /** @brief Sub-command identifier from @ref mrq_bwmgr_cmd. */
uint32_t cmd;
union {
struct cmd_bwmgr_query_abi_request query_abi;
@@ -2285,12 +2989,12 @@ struct mrq_bwmgr_request {
} BPMP_UNION_ANON;
} BPMP_ABI_PACKED;
-/*
- * @brief Response to MRQ_BWMGR
+/**
+ * @brief Response payload for the #MRQ_BWMGR -command.
*
- * |sub-command |payload |
- * |----------------------------|------------------------------|
- * |CMD_BWMGR_CALC_RATE | cmd_bwmgr_calc_rate_response |
+ * |Sub-command |Payload |
+ * |----------------------|------------------------------|
+ * |#CMD_BWMGR_CALC_RATE |#cmd_bwmgr_calc_rate_response |
*/
struct mrq_bwmgr_response {
union {
@@ -2299,15 +3003,13 @@ struct mrq_bwmgr_response {
} BPMP_ABI_PACKED;
/** @} BWMGR */
-/** @endcond (bpmp_t234 || bpmp_t239 || bpmp_th500) */
+/** @endcond */
-/**
+/** @cond (!bpmp_safe && (bpmp_t234 || bpmp_t238 || bpmp_t264))
* @ingroup MRQ_Codes
* @def MRQ_BWMGR_INT
- * @brief bpmp-integrated bwmgr requests
+ * @brief BPMP-FW integrated BWMGR requests
*
- * * Platforms: T234 onwards
- * @cond (bpmp_t234 || bpmp_t239 || bpmp_th500)
* * Initiators: CCPLEX
* * Targets: BPMP
* * Request Payload: @ref mrq_bwmgr_int_request
@@ -2317,10 +3019,13 @@ struct mrq_bwmgr_response {
* @{
*/
+/**
+ * @brief Sub-command identifiers for #MRQ_BWMGR_INT
+ */
enum mrq_bwmgr_int_cmd {
/**
* @brief Check whether the BPMP-FW supports the specified
- * request type
+ * sub-command.
*
* mrq_response::err is 0 if the specified request is
* supported and -#BPMP_ENODEV otherwise.
@@ -2328,36 +3033,64 @@ enum mrq_bwmgr_int_cmd {
CMD_BWMGR_INT_QUERY_ABI = 1,
/**
- * @brief Determine and set dram rate to satisfy iso/niso bw request
+ * @brief Determine and set DRAM rate to satisfy ISO/NISO bandwidth requests.
*
- * mrq_response::err is
- * * 0: request succeeded.
- * * -#BPMP_EINVAL: Invalid request parameters.
- * set_frequency in @ref cmd_bwmgr_int_calc_and_set_response
- * will not be set.
- * * -#BPMP_ENOTSUP: Requested bw is not available.
- * set_frequency in @ref cmd_bwmgr_int_calc_and_set_response
- * will be current dram-clk rate.
+ * mrq_response::err is defined as:
+ *
+ * |Value |Description |
+ * |-----------------|----------------------------------------------------------------------------------------------------------------|
+ * |0 |Request succeeded. |
+ * |-#BPMP_EINVAL |Invalid request parameters, cmd_bwmgr_int_calc_and_set_response::rate is not set. |
+ * |-#BPMP_ENOTSUP |Requested bandwidth is not available, cmd_bwmgr_int_calc_and_set_response::rate is the current DRAM clock rate. |
+ * |<0 |Any other internal error. |
*/
CMD_BWMGR_INT_CALC_AND_SET = 2,
/**
- * @brief Set a max DRAM frequency for the bandwidth-manager
+ * @brief Set a max DRAM frequency for the bandwidth manager.
*
- * mrq_response::err is
- * * 0: request succeeded.
- * * -#BPMP_ENOTSUP: Requested cap frequency is not possible.
+ * mrq_response::err is defined as:
+ *
+ * |Value |Description |
+ * |-----------------|------------------------------------------|
+ * |0 |Request succeeded. |
+ * |-#BPMP_ENOTSUP |Requested cap frequency is not possible. |
+ * |<0 |Any other internal error. |
*/
- CMD_BWMGR_INT_CAP_SET = 3
+ CMD_BWMGR_INT_CAP_SET = 3,
+
+ /**
+ * @brief Obtain the maximum amount of bandwidth currently allocatable
+ * to the requesting client.
+ *
+ * mrq_response::err is defined as:
+ *
+ * |Value |Description |
+ * |-----------------|------------------------------------------|
+ * |0 |Request succeeded. |
+ * |-#BPMP_EINVAL |Invalid request parameters. |
+ * |<0 |Any other internal error. |
+ */
+ CMD_BWMGR_INT_CURR_AVAILABLE_BW = 4,
+ /**
+ * @brief Get the last request made by the client.
+ *
+ * mrq_response::err is defined as:
+ *
+ * |Value |Description |
+ * |-----------------|------------------------------------------|
+ * |0 |Request succeeded. |
+ * |-#BPMP_EINVAL |Invalid request parameters. |
+ * |<0 |Any other internal error. |
+ */
+ CMD_BWMGR_INT_GET_LAST_REQUEST = 5,
};
-/*
- * request structure for request type CMD_BWMGR_QUERY_ABI
- *
- * type: Request type for which to check existence.
+/**
+ * @brief Request payload for #MRQ_BWMGR_INT sub-command #CMD_BWMGR_INT_QUERY_ABI
*/
struct cmd_bwmgr_int_query_abi_request {
- /* @brief request type determined by @ref mrq_bwmgr_int_cmd */
+ /** @brief Sub-command identifier from @ref mrq_bwmgr_int_cmd. */
uint32_t type;
} BPMP_ABI_PACKED;
@@ -2373,87 +3106,168 @@ struct cmd_bwmgr_int_query_abi_request {
/** @} bwmgr_int_unit_type */
-/*
- * request data for request type CMD_BWMGR_INT_CALC_AND_SET
+/**
+ * @brief Request payload for #MRQ_BWMGR_INT sub-command #CMD_BWMGR_INT_CALC_AND_SET
*/
struct cmd_bwmgr_int_calc_and_set_request {
- /* @brief bwmgr client ID @ref bpmp_bwmgr_ids */
+ /** @brief BWGMR client ID from @ref bpmp_bwmgr_ids */
uint32_t client_id;
- /* @brief average niso bw usage in kBps requested by client. */
+ /** @brief Average NISO bandwidth usage in kBps requested by client. */
uint32_t niso_bw;
- /*
- * @brief average iso bw usage in kBps requested by client.
- * Value is ignored if client is niso. Determined by client_id.
+ /**
+ * @brief Average ISO bandwidth usage in kBps requested by client.
+ *
+ * Value is ignored if client is NISO as determined by #client_id.
*/
uint32_t iso_bw;
- /*
- * @brief memory clock floor requested by client.
- * Unit determined by floor_unit.
+ /**
+ * @brief Memory clock floor requested by client, unit of the value
+ * is determined by #floor_unit -field.
*/
uint32_t mc_floor;
- /*
- * @brief toggle to determine the unit-type of floor value.
- * See @ref bwmgr_int_unit_type definitions for unit-type mappings.
+ /**
+ * @brief Value set to determine the unit of the #mc_floor value:
+ *
+ * | Value | Unit |
+ * |-----------------------|----------------------|
+ * | #BWMGR_INT_UNIT_KBPS | Kilobytes per second |
+ * | #BWMGR_INT_UNIT_KHZ | Kilohertz |
*/
uint8_t floor_unit;
} BPMP_ABI_PACKED;
-struct cmd_bwmgr_int_cap_set_request {
- /* @brief requested cap frequency in Hz. */
+/**
+ * @brief Response payload for #MRQ_BWMGR_INT sub-command #CMD_BWMGR_INT_CALC_AND_SET
+ */
+struct cmd_bwmgr_int_calc_and_set_response {
+ /** @brief Currently set memory clock frequency in Hz */
uint64_t rate;
} BPMP_ABI_PACKED;
-/*
- * response data for request type CMD_BWMGR_CALC_AND_SET
+/**
+ * @brief Request payload for #MRQ_BWMGR_INT sub-command #CMD_BWMGR_INT_CAP_SET
*/
-struct cmd_bwmgr_int_calc_and_set_response {
- /* @brief current set memory clock frequency in Hz */
+struct cmd_bwmgr_int_cap_set_request {
+ /** @brief Requested cap frequency in Hz. */
uint64_t rate;
} BPMP_ABI_PACKED;
-/*
- * @brief Request with #MRQ_BWMGR_INT
+/**
+ * @brief Request payload for #MRQ_BWMGR_INT sub-command #CMD_BWMGR_INT_CURR_AVAILABLE_BW
+ */
+struct cmd_bwmgr_int_curr_available_bw_request {
+ /** @brief BWMGR client ID from @ref bpmp_bwmgr_ids */
+ uint32_t id;
+} BPMP_ABI_PACKED;
+
+/**
+ * @brief Response payload for #MRQ_BWMGR_INT sub-command #CMD_BWMGR_INT_CURR_AVAILABLE_BW
+ */
+struct cmd_bwmgr_int_curr_available_bw_response {
+ /** @brief Current cap frequency in KHz. */
+ uint64_t cap_rate;
+ /** @brief Currently available bandwidth for the requesting client
+ * to allocate in KBps.
+ */
+ uint64_t available_bw;
+} BPMP_ABI_PACKED;
+
+struct cmd_bwmgr_int_get_last_request_request {
+ /** @brief BWMGR client ID from @ref bpmp_bwmgr_ids */
+ uint32_t id;
+ /**
+ * @brief Value set to determine the unit of the returned mc_floor value:
+ *
+ * | Value | Unit |
+ * |-----------------------|----------------------|
+ * | #BWMGR_INT_UNIT_KBPS | Kilobytes per second |
+ * | #BWMGR_INT_UNIT_KHZ | Kilohertz |
+ */
+ uint8_t floor_unit;
+} BPMP_ABI_PACKED;
+
+struct cmd_bwmgr_int_get_last_request_response {
+ /** @brief BWGMR client ID from @ref bpmp_bwmgr_ids */
+ uint32_t client_id;
+ /** @brief Average NISO bandwidth usage in kBps requested by client. */
+ uint32_t niso_bw;
+ /**
+ * @brief Average ISO bandwidth usage in kBps requested by client.
+ */
+ uint32_t iso_bw;
+ /**
+ * @brief Memory clock floor requested by client, unit of the value
+ * is determined by #floor_unit -field.
+ */
+ uint32_t mc_floor;
+ /**
+ * @brief Value set to determine the unit of the #mc_floor value:
+ *
+ * | Value | Unit |
+ * |-----------------------|----------------------|
+ * | #BWMGR_INT_UNIT_KBPS | Kilobytes per second |
+ * | #BWMGR_INT_UNIT_KHZ | Kilohertz |
+ */
+ uint8_t floor_unit;
+} BPMP_ABI_PACKED;
+
+/**
+ * @brief Request payload for the #MRQ_BWMGR_INT -command.
*
+ * |Sub-command |Payload |
+ * |---------------------------------|-----------------------------------------|
+ * |#CMD_BWMGR_INT_QUERY_ABI |#cmd_bwmgr_int_query_abi_request |
+ * |#CMD_BWMGR_INT_CALC_AND_SET |#cmd_bwmgr_int_calc_and_set_request |
+ * |#CMD_BWMGR_INT_CAP_SET |#cmd_bwmgr_int_cap_set_request |
+ * |#CMD_BWMGR_INT_GET_LAST_REQUEST |#cmd_bwmgr_int_get_last_request_request |
*
- * |sub-command |payload |
- * |----------------------------|-----------------------------------|
- * |CMD_BWMGR_INT_QUERY_ABI | cmd_bwmgr_int_query_abi_request |
- * |CMD_BWMGR_INT_CALC_AND_SET | cmd_bwmgr_int_calc_and_set_request|
- * |CMD_BWMGR_INT_CAP_SET | cmd_bwmgr_int_cap_set_request |
+ * The following additional sub-commands are supported on T264 platforms:
*
+ * |Sub-command |Payload |
+ * |---------------------------------|-----------------------------------------|
+ * |#CMD_BWMGR_INT_CURR_AVAILABLE_BW |#cmd_bwmgr_int_curr_available_bw_request |
*/
struct mrq_bwmgr_int_request {
+ /** @brief Sub-command identifier from @ref mrq_bwmgr_int_cmd. */
uint32_t cmd;
union {
struct cmd_bwmgr_int_query_abi_request query_abi;
struct cmd_bwmgr_int_calc_and_set_request bwmgr_calc_set_req;
struct cmd_bwmgr_int_cap_set_request bwmgr_cap_set_req;
+ struct cmd_bwmgr_int_curr_available_bw_request bwmgr_curr_available_bw_req;
+ struct cmd_bwmgr_int_get_last_request_request bwmgr_get_last_request_req;
} BPMP_UNION_ANON;
} BPMP_ABI_PACKED;
-/*
- * @brief Response to MRQ_BWMGR_INT
+/**
+ * @brief Response payload for the #MRQ_BWMGR_INT -command.
+ *
+ * |Sub-command |Payload |
+ * |---------------------------------|------------------------------------------|
+ * |#CMD_BWMGR_INT_CALC_AND_SET |#cmd_bwmgr_int_calc_and_set_response |
+ * |#CMD_BWMGR_INT_GET_LAST_REQUEST |#cmd_bwmgr_int_get_last_request_response |
*
- * |sub-command |payload |
- * |----------------------------|---------------------------------------|
- * |CMD_BWMGR_INT_CALC_AND_SET | cmd_bwmgr_int_calc_and_set_response |
+ * The following additional sub-commands are supported on T264 platforms:
+ * |Sub-command |Payload |
+ * |---------------------------------|------------------------------------------|
+ * |#CMD_BWMGR_INT_CURR_AVAILABLE_BW |#cmd_bwmgr_int_curr_available_bw_response |
*/
struct mrq_bwmgr_int_response {
union {
struct cmd_bwmgr_int_calc_and_set_response bwmgr_calc_set_resp;
+ struct cmd_bwmgr_int_curr_available_bw_response bwmgr_curr_available_bw_resp;
+ struct cmd_bwmgr_int_get_last_request_response bwmgr_get_last_request_resp;
} BPMP_UNION_ANON;
} BPMP_ABI_PACKED;
/** @} BWMGR_INT */
-/** @endcond (bpmp_t234 || bpmp_t239 || bpmp_th500) */
+/** @endcond */
-/**
+/** @cond (!bpmp_safe && (bpmp_t234 || bpmp_t238 || bpmp_t264))
* @ingroup MRQ_Codes
* @def MRQ_ISO_CLIENT
* @brief ISO client requests
*
- * * Platforms: T234 onwards
- * @cond (bpmp_t234 || bpmp_t239 || bpmp_th500)
* * Initiators: CCPLEX
* * Targets: BPMP
* * Request Payload: @ref mrq_iso_client_request
@@ -2463,148 +3277,178 @@ struct mrq_bwmgr_int_response {
* @{
*/
+/**
+ * @brief Sub-command identifiers for #MRQ_ISO_CLIENT.
+ */
enum mrq_iso_client_cmd {
/**
- * @brief Check whether the BPMP driver supports the specified
- * request type
+ * @brief Check whether BPMP-FW supports a specified
+ * #MRQ_ISO_CLIENT sub-command.
*
* mrq_response::err is 0 if the specified request is
* supported and -#BPMP_ENODEV otherwise.
*/
CMD_ISO_CLIENT_QUERY_ABI = 0,
- /*
- * @brief check for legal LA for the iso client. Without programming
- * LA MC registers, calculate and ensure that legal LA is possible for
- * iso bw requested by the ISO client.
+ /**
+ * @brief Determine legal LA for ISO client.
*
- * mrq_response::err is
- * * 0: check la succeeded.
- * * -#BPMP_EINVAL: Invalid request parameters.
- * * -#BPMP_EFAULT: Legal LA is not possible for client requested iso_bw
+ * Without programming LA MC registers, calculate and ensure that
+ * a legal LA is possible for the ISO bandwidth requested by the
+ * ISO client.
+ *
+ * mrq_response::err for this sub-command is defined as:
+ *
+ * | Value | Description |
+ * |---------------|--------------------------------------------------------------|
+ * | 0 | Request successful and legal LA is possible. |
+ * | -#BPMP_EINVAL | Invalid request parameters. |
+ * | -#BPMP_EFAULT | Legal LA is not possible for client requested ISO bandwidth. |
+ * | <0 | Any other internal error. |
*/
CMD_ISO_CLIENT_CALCULATE_LA = 1,
- /*
- * @brief set LA for the iso client. Calculate and program the LA/PTSA
- * MC registers corresponding to the client making bw request
+ /**
+ * @brief Set LA for ISO client.
*
- * mrq_response::err is
- * * 0: set la succeeded.
- * * -#BPMP_EINVAL: Invalid request parameters.
- * * -#BPMP_EFAULT: Failed to calculate or program MC registers.
+ * Calculate and program the LA/PTSA MC registers corresponding to the
+ * ISO client making the bandwidth request.
+ *
+ * mrq_response::err for this sub-command is defined as:
+ *
+ * | Value | Description |
+ * |---------------|----------------------------------------------|
+ * | 0 | Setting LA succeeded. |
+ * | -#BPMP_EINVAL | Invalid request parameters. |
+ * | -#BPMP_EFAULT | Failed to calculate or program MC registers. |
+ * | <0 | Any other internal error. |
*/
CMD_ISO_CLIENT_SET_LA = 2,
- /*
- * @brief Get max possible bw for iso client
+ /**
+ * @brief Get maximum possible bandwidth for ISO client.
*
- * mrq_response::err is
- * * 0: get_max_bw succeeded.
- * * -#BPMP_EINVAL: Invalid request parameters.
+ * mrq_response::err for this sub-command is defined as:
+ *
+ * | Value | Description |
+ * |---------------|----------------------------------------------|
+ * | 0 | Operation successful. |
+ * | -#BPMP_EINVAL | Invalid request parameters. |
+ * | <0 | Any other internal error. |
*/
CMD_ISO_CLIENT_GET_MAX_BW = 3
};
-/*
- * request data for request type CMD_ISO_CLIENT_QUERY_ABI
- *
- * type: Request type for which to check existence.
+/**
+ * @brief Request payload for #MRQ_ISO_CLIENT sub-command #CMD_ISO_CLIENT_QUERY_ABI
*/
struct cmd_iso_client_query_abi_request {
+ /**
+ * @brief Sub-command identifier from @ref mrq_iso_client_cmd
+ * for which to check existence.
+ */
uint32_t type;
} BPMP_ABI_PACKED;
-/*
- * request data for request type CMD_ISO_CLIENT_CALCULATE_LA
- *
- * id: client ID in @ref bpmp_bwmgr_ids
- * bw: bw requested in kBps by client ID.
- * init_bw_floor: initial dram_bw_floor in kBps passed by client ID.
- * ISO client will perform mempool allocation and DVFS buffering based
- * on this dram_bw_floor.
+/**
+ * @brief Request payload #MRQ_ISO_CLIENT sub-command #CMD_ISO_CLIENT_CALCULATE_LA
*/
struct cmd_iso_client_calculate_la_request {
+ /** @brief BWMGR client ID from @ref bpmp_bwmgr_ids */
uint32_t id;
+ /** @brief Bandwidth requested in kBps for the client specified in #id. */
uint32_t bw;
+ /**
+ * @brief Initial DRAM bandwidth floor in kBps for the ISO client specified in #id.
+ *
+ * ISO client will perform mempool allocation and DVFS buffering based
+ * on this value.
+ */
uint32_t init_bw_floor;
} BPMP_ABI_PACKED;
-/*
- * request data for request type CMD_ISO_CLIENT_SET_LA
- *
- * id: client ID in @ref bpmp_bwmgr_ids
- * bw: bw requested in kBps by client ID.
- * final_bw_floor: final dram_bw_floor in kBps.
- * Sometimes the initial dram_bw_floor passed by ISO client may need to be
- * updated by considering higher dram freq's. This is the final dram_bw_floor
- * used to calculate and program MC registers.
+/**
+ * @brief Response payload for #MRQ_ISO_CLIENT sub-command #CMD_ISO_CLIENT_CALCULATE_LA
+ */
+struct cmd_iso_client_calculate_la_response {
+ /** @brief Minimum DRAM rate in kHz at which a legal LA is possible */
+ uint32_t la_rate_floor;
+ /**
+ * Minimum DRAM frequency in kHz required to satisfy this clients
+ * ISO bandwidth request, assuming all other ISO clients are inactive.
+ */
+ uint32_t iso_client_only_rate;
+} BPMP_ABI_PACKED;
+
+/**
+ * @brief Request payload for #MRQ_ISO_CLIENT sub-command #CMD_ISO_CLIENT_SET_LA
*/
struct cmd_iso_client_set_la_request {
+ /** @brief BMWGR client ID from @ref bpmp_bwmgr_ids */
uint32_t id;
+ /** @brief Bandwidth requested in kBps for the client specified in #id. */
uint32_t bw;
+ /**
+ * @brief Final DRAM bandwidth floor in kBps.
+ *
+ * Sometimes the initial cmd_iso_client_calculate_la_request::dram_bw_floor
+ * passed by ISO client may need to be updated by considering higher
+ * DRAM frequencies. This is the final DRAM bandwidth floor value used
+ * to calculate and program MC registers.
+ */
uint32_t final_bw_floor;
} BPMP_ABI_PACKED;
-/*
- * request data for request type CMD_ISO_CLIENT_GET_MAX_BW
- *
- * id: client ID in @ref bpmp_bwmgr_ids
+/**
+ * @brief Request payload for #MRQ_ISO_CLIENT sub-command #CMD_ISO_CLIENT_GET_MAX_BW
*/
struct cmd_iso_client_get_max_bw_request {
+ /** @brief BWMGR client ID from @ref bpmp_bwmgr_ids */
uint32_t id;
} BPMP_ABI_PACKED;
-/*
- * response data for request type CMD_ISO_CLIENT_CALCULATE_LA
- *
- * la_rate_floor: minimum dram_rate_floor in kHz at which a legal la is possible
- * iso_client_only_rate: Minimum dram freq in kHz required to satisfy this clients
- * iso bw request, assuming all other iso clients are inactive
- */
-struct cmd_iso_client_calculate_la_response {
- uint32_t la_rate_floor;
- uint32_t iso_client_only_rate;
-} BPMP_ABI_PACKED;
-
/**
* @brief Used by @ref cmd_iso_client_get_max_bw_response
*/
struct iso_max_bw {
- /* @brief dram frequency in kHz */
+ /** @brief dram frequency in kHz */
uint32_t freq;
- /* @brief max possible iso-bw in kBps */
+ /** @brief max possible iso-bw in kBps */
uint32_t iso_bw;
} BPMP_ABI_PACKED;
+/**
+ * @brief Size of the cmd_iso_client_get_max_bw_response::pairs -array.
+ */
#define ISO_MAX_BW_MAX_SIZE 14U
-/*
- * response data for request type CMD_ISO_CLIENT_GET_MAX_BW
+
+/**
+ * @brief Response payload for #MRQ_ISO_CLIENT sub-command #CMD_ISO_CLIENT_GET_MAX_BW
*/
struct cmd_iso_client_get_max_bw_response {
- /* @brief The number valid entries in iso_max_bw pairs */
+ /** @brief The number valid entries in iso_max_bw pairs */
uint32_t num_pairs;
- /* @brief max ISOBW <dram freq, max bw> information */
+ /** @brief max ISOBW <dram freq, max bw> information */
struct iso_max_bw pairs[ISO_MAX_BW_MAX_SIZE];
} BPMP_ABI_PACKED;
/**
- * @brief Request with #MRQ_ISO_CLIENT
- *
- * Used by the sender of an #MRQ_ISO_CLIENT message.
+ * @brief Request payload for #MRQ_ISO_CLIENT command.
*
- * |sub-command |payload |
- * |------------------------------------ |----------------------------------------|
- * |CMD_ISO_CLIENT_QUERY_ABI |cmd_iso_client_query_abi_request |
- * |CMD_ISO_CLIENT_CALCULATE_LA |cmd_iso_client_calculate_la_request |
- * |CMD_ISO_CLIENT_SET_LA |cmd_iso_client_set_la_request |
- * |CMD_ISO_CLIENT_GET_MAX_BW |cmd_iso_client_get_max_bw_request |
+ * Each #MRQ_ISO_CLIENT -command is expected to include a sub-command specific
+ * payload as defined in table below:
*
+ * |Sub-command |Request payload |
+ * |-----------------------------|--------------------------------------|
+ * |#CMD_ISO_CLIENT_QUERY_ABI |#cmd_iso_client_query_abi_request |
+ * |#CMD_ISO_CLIENT_CALCULATE_LA |#cmd_iso_client_calculate_la_request |
+ * |#CMD_ISO_CLIENT_SET_LA |#cmd_iso_client_set_la_request |
+ * |#CMD_ISO_CLIENT_GET_MAX_BW |#cmd_iso_client_get_max_bw_request |
*/
-
struct mrq_iso_client_request {
- /* Type of request. Values listed in enum mrq_iso_client_cmd */
+ /** @brief Sub-command identifier from @ref mrq_iso_client_cmd. */
uint32_t cmd;
+
union {
struct cmd_iso_client_query_abi_request query_abi;
struct cmd_iso_client_calculate_la_request calculate_la_req;
@@ -2614,20 +3458,20 @@ struct mrq_iso_client_request {
} BPMP_ABI_PACKED;
/**
- * @brief Response to MRQ_ISO_CLIENT
+ * @brief Response payload for #MRQ_ISO_CLIENT command.
*
- * Each sub-command supported by @ref mrq_iso_client_request may return
- * sub-command-specific data. Some do and some do not as indicated in
- * the following table
+ * Some of the sub-commands supported by #MRQ_ISO_CLIENT may return
+ * a sub-command -specific payload in the MRQ response as defined in table
+ * below:
*
- * |sub-command |payload |
- * |---------------------------- |------------------------------------|
- * |CMD_ISO_CLIENT_CALCULATE_LA |cmd_iso_client_calculate_la_response|
- * |CMD_ISO_CLIENT_SET_LA |N/A |
- * |CMD_ISO_CLIENT_GET_MAX_BW |cmd_iso_client_get_max_bw_response |
+ * |Sub-command |Response payload |
+ * |---------------------------- |--------------------------------------|
+ * |#CMD_ISO_CLIENT_QUERY_ABI |- |
+ * |#CMD_ISO_CLIENT_CALCULATE_LA |#cmd_iso_client_calculate_la_response |
+ * |#CMD_ISO_CLIENT_SET_LA |- |
+ * |#CMD_ISO_CLIENT_GET_MAX_BW |#cmd_iso_client_get_max_bw_response |
*
*/
-
struct mrq_iso_client_response {
union {
struct cmd_iso_client_calculate_la_response calculate_la_resp;
@@ -2636,15 +3480,13 @@ struct mrq_iso_client_response {
} BPMP_ABI_PACKED;
/** @} ISO_CLIENT */
-/** @endcond (bpmp_t234 || bpmp_t239 || bpmp_th500) */
+/** @endcond */
-/**
+/** @cond (!bpmp_t186)
* @ingroup MRQ_Codes
* @def MRQ_CPU_NDIV_LIMITS
- * @brief CPU freq. limits in ndiv
+ * @brief Return CPU cluster NDIV limits
*
- * * Platforms: T194 onwards
- * @cond (bpmp_t194 || bpmp_t234 || bpmp_t239 || bpmp_th500)
* * Initiators: CCPLEX
* * Targets: BPMP
* * Request Payload: @ref mrq_cpu_ndiv_limits_request
@@ -2654,10 +3496,10 @@ struct mrq_iso_client_response {
*/
/**
- * @brief Request for ndiv limits of a cluster
+ * @brief Request payload for the #MRQ_CPU_NDIV_LIMITS -command
*/
struct mrq_cpu_ndiv_limits_request {
- /** @brief Enum cluster_id */
+ /** @brief Logical CPU cluster identifier */
uint32_t cluster_id;
} BPMP_ABI_PACKED;
@@ -2678,15 +3520,14 @@ struct mrq_cpu_ndiv_limits_response {
} BPMP_ABI_PACKED;
/** @} CPU */
-/** @endcond (bpmp_t194 || bpmp_t234 || bpmp_t239 || bpmp_th500) */
+/** @endcond */
-/**
+
+/** @cond (bpmp_t194)
* @ingroup MRQ_Codes
* @def MRQ_CPU_AUTO_CC3
* @brief Query CPU cluster auto-CC3 configuration
*
- * * Platforms: T194
- * @cond bpmp_t194
* * Initiators: CCPLEX
* * Targets: BPMP
* * Request Payload: @ref mrq_cpu_auto_cc3_request
@@ -2702,15 +3543,15 @@ struct mrq_cpu_ndiv_limits_response {
*/
/**
- * @brief Request for auto-CC3 configuration of a cluster
+ * @brief Request payload for the #MRQ_CPU_AUTO_CC3 -command
*/
struct mrq_cpu_auto_cc3_request {
- /** @brief Enum cluster_id (logical cluster id, known to CCPLEX s/w) */
+ /** @brief Logical CPU cluster ID */
uint32_t cluster_id;
} BPMP_ABI_PACKED;
/**
- * @brief Response to #MRQ_CPU_AUTO_CC3
+ * @brief Response payload for the #MRQ_CPU_AUTO_CC3 -command
*/
struct mrq_cpu_auto_cc3_response {
/**
@@ -2724,9 +3565,9 @@ struct mrq_cpu_auto_cc3_response {
} BPMP_ABI_PACKED;
/** @} CC3 */
-/** @endcond bpmp_t194 */
+/** @endcond */
-/**
+/** @cond (bpmp_t186 || bpmp_t194 || bpmp_t234)
* @ingroup MRQ_Codes
* @def MRQ_RINGBUF_CONSOLE
* @brief A ring buffer debug console for BPMP
@@ -2811,7 +3652,9 @@ struct cmd_ringbuf_console_query_abi_resp {
*/
struct cmd_ringbuf_console_read_req {
/**
- * @brief Number of bytes requested to be read from the BPMP TX buffer
+ * @brief Number of bytes requested to be read from the BPMP TX buffer.
+ *
+ * Valid range is [0, #MRQ_RINGBUF_CONSOLE_MAX_READ_LEN]
*/
uint8_t len;
} BPMP_ABI_PACKED;
@@ -2823,7 +3666,11 @@ struct cmd_ringbuf_console_read_req {
struct cmd_ringbuf_console_read_resp {
/** @brief The actual data read from the BPMP TX buffer */
uint8_t data[MRQ_RINGBUF_CONSOLE_MAX_READ_LEN];
- /** @brief Number of bytes in cmd_ringbuf_console_read_resp::data */
+ /**
+ * @brief Number of bytes in cmd_ringbuf_console_read_resp::data
+ *
+ * Valid range is [0, #MRQ_RINGBUF_CONSOLE_MAX_WRITE_LEN]
+ */
uint8_t len;
} BPMP_ABI_PACKED;
@@ -2904,14 +3751,13 @@ union mrq_ringbuf_console_bpmp_to_host_response {
} BPMP_ABI_PACKED;
/** @} RingbufConsole */
+/** @endcond */
-/**
+/** @cond (!bpmp_t186 && !(bpmp_safe && bpmp_t234))
* @ingroup MRQ_Codes
* @def MRQ_STRAP
* @brief Set a strap value controlled by BPMP
*
- * * Platforms: T194 onwards
- * @cond (bpmp_t194 || bpmp_t234 || bpmp_t239 || bpmp_th500)
* * Initiators: CCPLEX
* * Targets: BPMP
* * Request Payload: @ref mrq_strap_request
@@ -2925,10 +3771,14 @@ union mrq_ringbuf_console_bpmp_to_host_response {
* deasserted.
*
* BPMP owns registers which act as straps to various units. It
- * exposes limited control of those straps via #MRQ_STRAP.
+ * exposes limited control of those registers via #MRQ_STRAP.
*
* @{
*/
+
+/**
+ * @brief Sub-command identifiers for the #MRQ_STRAP -command.
+ */
enum mrq_strap_cmd {
/** @private */
STRAP_RESERVED = 0,
@@ -2937,27 +3787,31 @@ enum mrq_strap_cmd {
};
/**
- * @brief Request with #MRQ_STRAP
+ * @brief Request payload for the #MRQ_STRAP -command.
*/
struct mrq_strap_request {
- /** @brief @ref mrq_strap_cmd */
+ /** @brief Sub-command identifier from @ref mrq_strap_cmd */
uint32_t cmd;
- /** @brief Strap ID from @ref Strap_Identifiers */
+ /**
+ * @if (bpmp_t234 || bpmp_th500 || bpmp_t264)
+ * @brief Strap ID from @ref bpmp_strap_ids
+ * @else
+ * @brief Strap ID (undefined)
+ * @endif
+ */
uint32_t id;
- /** @brief Desired value for strap (if cmd is #STRAP_SET) */
+ /** @brief Desired value for strap (if #cmd is #STRAP_SET) */
uint32_t value;
} BPMP_ABI_PACKED;
/** @} Strap */
-/** @endcond (bpmp_t194 || bpmp_t234 || bpmp_t239 || bpmp_th500) */
+/** @endcond */
-/**
+/** @cond (bpmp_t194 || bpmp_t234 || bpmp_th500)
* @ingroup MRQ_Codes
* @def MRQ_UPHY
* @brief Perform a UPHY operation
*
- * * Platforms: T194 onwards
- * @cond (bpmp_t194 || bpmp_t234 || bpmp_t239 || bpmp_th500)
* * Initiators: CCPLEX
* * Targets: BPMP
* * Request Payload: @ref mrq_uphy_request
@@ -2966,90 +3820,215 @@ struct mrq_strap_request {
* @addtogroup UPHY
* @{
*/
-enum {
+
+/**
+ * @brief Sub-command identifiers for #MRQ_UPHY.
+ */
+enum mrq_uphy_cmd {
+ /** @brief Trigger PCIE lane margining procedure. */
CMD_UPHY_PCIE_LANE_MARGIN_CONTROL = 1,
+ /** @brief Return PCIE lane margining status. */
CMD_UPHY_PCIE_LANE_MARGIN_STATUS = 2,
+ /** @brief Initialize PCIE EP PLL controller. */
CMD_UPHY_PCIE_EP_CONTROLLER_PLL_INIT = 3,
+ /** @brief Set state of the PCIE RP/EP controller. */
CMD_UPHY_PCIE_CONTROLLER_STATE = 4,
+ /** @brief Disable PCIE EP PLL controller. */
CMD_UPHY_PCIE_EP_CONTROLLER_PLL_OFF = 5,
+
+ /**
+ * @cond bpmp_t238
+ * @brief Initialize and enable UPHY display port.
+ */
CMD_UPHY_DISPLAY_PORT_INIT = 6,
+ /** @brief Disable UPHY display port. */
CMD_UPHY_DISPLAY_PORT_OFF = 7,
+ /** @brief Trigger sequence to restore XUSB DYN lanes during SC7 exit. */
CMD_UPHY_XUSB_DYN_LANES_RESTORE = 8,
+ /** @endcond */
+
+ /**
+ * @cond bpmp_th500
+ * @brief Perform UPHY Lane EOM scan.
+ */
+ CMD_UPHY_LANE_EOM_SCAN = 9,
+ /** @brief Config PCIe VDM with a given BDF ID. */
+ CMD_UPHY_PCIE_CONFIG_VDM = 10,
+ /** @endcond */
+
CMD_UPHY_MAX,
};
+/**
+ * @brief Request payload for #MRQ_UPHY sub-command #CMD_UPHY_PCIE_LANE_MARGIN_CONTROL.
+ */
struct cmd_uphy_margin_control_request {
- /** @brief Enable margin */
+ /**
+ * @brief Enable margin.
+ *
+ * Valid values:
+ * * Value 0 disables margin,
+ * * Value 1 enables margin.
+ */
int32_t en;
- /** @brief Clear the number of error and sections */
+ /**
+ * @brief Clear the number of error and sections.
+ *
+ * Valid values:
+ *
+ * * Value 0: Skip clear,
+ * * Value 1: Perform clear.
+ */
int32_t clr;
- /** @brief Set x offset (1's complement) for left/right margin type (y should be 0) */
+ /**
+ * @brief Set x offset (1's complement) for left/right margin type (y should be 0).
+ *
+ * Valid range is [0, 127]
+ */
uint32_t x;
- /** @brief Set y offset (1's complement) for left/right margin type (x should be 0) */
+ /**
+ * @brief Set y offset (1's complement) for left/right margin type (x should be 0)
+ *
+ * Valid range is [0, 63]
+ */
uint32_t y;
- /** @brief Set number of bit blocks for each margin section */
+ /**
+ * @brief Set number of bit blocks for each margin section.
+ *
+ * Valid range is [0, 15]
+ */
uint32_t nblks;
} BPMP_ABI_PACKED;
+/**
+ * @brief Response payload for #MRQ_UPHY sub-command #CMD_UPHY_PCIE_LANE_MARGIN_STATUS.
+ */
struct cmd_uphy_margin_status_response {
/** @brief Number of errors observed */
uint32_t status;
} BPMP_ABI_PACKED;
+/**
+ * @brief Request payload for #MRQ_UPHY sub-command #CMD_UPHY_PCIE_EP_CONTROLLER_PLL_INIT.
+ */
struct cmd_uphy_ep_controller_pll_init_request {
- /** @brief EP controller number, T194 valid: 0, 4, 5; T234 valid: 5, 6, 7, 10; T239 valid: 0 */
+ /** @brief EP controller number, T194 valid: 0, 4, 5; T234 valid: 5, 6, 7, 10; T238 valid: 0 */
uint8_t ep_controller;
} BPMP_ABI_PACKED;
+/**
+ * @brief Request payload for #MRQ_UPHY sub-command #CMD_UPHY_PCIE_CONTROLLER_STATE.
+ */
struct cmd_uphy_pcie_controller_state_request {
- /** @brief PCIE controller number, T194 valid: 0-4; T234 valid: 0-10; T239 valid: 0-3 */
+ /** @brief PCIE controller number, T194 valid: 0-4; T234 valid: 0-10; T238 valid: 0-3 */
uint8_t pcie_controller;
+ /** @brief Nonzero value to enable controller, zero value to disable */
uint8_t enable;
} BPMP_ABI_PACKED;
+/**
+ * @brief Request payload for #MRQ_UPHY sub-command #CMD_UPHY_PCIE_EP_CONTROLLER_PLL_OFF.
+ */
struct cmd_uphy_ep_controller_pll_off_request {
- /** @brief EP controller number, T194 valid: 0, 4, 5; T234 valid: 5, 6, 7, 10; T239 valid: 0 */
+ /** @brief EP controller number, T194 valid: 0, 4, 5; T234 valid: 5, 6, 7, 10; T238 valid: 0 */
uint8_t ep_controller;
} BPMP_ABI_PACKED;
+/**
+ * @cond bpmp_t238
+ * @brief Request payload for #MRQ_UPHY sub-command #CMD_UPHY_DISPLAY_PORT_INIT.
+ */
struct cmd_uphy_display_port_init_request {
- /** @brief DisplayPort link rate, T239 valid: 1620, 2700, 5400, 8100, 2160, 2430, 3240, 4320, 6750 */
+ /** @brief DisplayPort link rate, T238 valid: 1620, 2700, 5400, 8100, 2160, 2430, 3240, 4320, 6750 */
uint16_t link_rate;
/** @brief 1: lane 0; 2: lane 1; 3: lane 0 and 1 */
uint16_t lanes_bitmap;
} BPMP_ABI_PACKED;
+/**
+ * @brief Request payload for #MRQ_UPHY sub-command #CMD_UPHY_XUSB_DYN_LANES_RESTORE.
+ */
struct cmd_uphy_xusb_dyn_lanes_restore_request {
/** @brief 1: lane 0; 2: lane 1; 3: lane 0 and 1 */
uint16_t lanes_bitmap;
} BPMP_ABI_PACKED;
+/** @endcond */
+
+/**
+ * @cond bpmp_th500
+ * @brief Request payload for #MRQ_UPHY sub-command #CMD_UPHY_LANE_EOM_SCAN
+ */
+struct cmd_uphy_lane_eom_scan_request {
+ /** @brief UPHY brick number, valid: 0-5 */
+ uint32_t brick;
+ /** @brief UPHY lane number, valid: 0-15 for UPHY0-UPHY3, 0-1 for UPHY4-UPHY5 */
+ uint32_t lane;
+ /** @brief Perform EOM for PCIE GEN5 link: 1 for yes, 0 for no. */
+ uint32_t pcie_gen5;
+} BPMP_ABI_PACKED;
+
+/**
+ * @brief Response payload for #MRQ_UPHY sub-command #CMD_UPHY_LANE_EOM_SCAN
+ */
+struct cmd_uphy_lane_eom_scan_response {
+ uint32_t data;
+} BPMP_ABI_PACKED;
+
+/**
+ * @brief Request payload for #MRQ_UPHY sub-command #CMD_UPHY_PCIE_CONFIG_VDM
+ */
+struct cmd_uphy_pcie_config_vdm_request {
+ uint8_t pcie_controller;
+ /**
+ * @brief Bus/Dev/Func ID to be programmed for VDM.
+ *
+ * - bits[15..8] Bus
+ * - bits[7..3] Dev
+ * - bit [2..0] Func
+ */
+ uint16_t bdf;
+} BPMP_ABI_PACKED;
+/** @endcond */
/**
* @ingroup UPHY
- * @brief Request with #MRQ_UPHY
+ * @brief Request payload for the #MRQ_UPHY -command.
*
* Used by the sender of an #MRQ_UPHY message to control UPHY.
* The uphy_request is split into several sub-commands. CMD_UPHY_PCIE_LANE_MARGIN_STATUS
* requires no additional data. Others have a sub-command specific payload. Below table
* shows sub-commands with their corresponding payload data.
*
- * |sub-command |payload |
- * |------------------------------------ |----------------------------------------|
- * |CMD_UPHY_PCIE_LANE_MARGIN_CONTROL |uphy_set_margin_control |
- * |CMD_UPHY_PCIE_LANE_MARGIN_STATUS | |
- * |CMD_UPHY_PCIE_EP_CONTROLLER_PLL_INIT |cmd_uphy_ep_controller_pll_init_request |
- * |CMD_UPHY_PCIE_CONTROLLER_STATE |cmd_uphy_pcie_controller_state_request |
- * |CMD_UPHY_PCIE_EP_CONTROLLER_PLL_OFF |cmd_uphy_ep_controller_pll_off_request |
- * |CMD_UPHY_PCIE_DISPLAY_PORT_INIT |cmd_uphy_display_port_init_request |
- * |CMD_UPHY_PCIE_DISPLAY_PORT_OFF | |
- * |CMD_UPHY_XUSB_DYN_LANES_RESTORE |cmd_uphy_xusb_dyn_lanes_restore_request |
+ * |sub-command |payload |
+ * |--------------------------------------|-----------------------------------------|
+ * |#CMD_UPHY_PCIE_LANE_MARGIN_CONTROL |#cmd_uphy_margin_control_request |
+ * |#CMD_UPHY_PCIE_LANE_MARGIN_STATUS |- |
+ * |#CMD_UPHY_PCIE_EP_CONTROLLER_PLL_INIT |#cmd_uphy_ep_controller_pll_init_request |
+ * |#CMD_UPHY_PCIE_CONTROLLER_STATE |#cmd_uphy_pcie_controller_state_request |
+ * |#CMD_UPHY_PCIE_EP_CONTROLLER_PLL_OFF |#cmd_uphy_ep_controller_pll_off_request |
+ *
+ * @cond bpmp_t238
+ * The following additional sub-commands are supported on T238 platforms:
*
+ * |sub-command |payload |
+ * |--------------------------------------|-----------------------------------------|
+ * |#CMD_UPHY_DISPLAY_PORT_INIT |#cmd_uphy_display_port_init_request |
+ * |#CMD_UPHY_DISPLAY_PORT_OFF |- |
+ * |#CMD_UPHY_XUSB_DYN_LANES_RESTORE |#cmd_uphy_xusb_dyn_lanes_restore_request |
+ * @endcond
+ *
+ * @cond bpmp_th500
+ * The following additional sub-commands are supported on TH500 platforms:
+ * |sub-command |payload |
+ * |--------------------------------------|-----------------------------------------|
+ * |#CMD_UPHY_LANE_EOM_SCAN |#cmd_uphy_lane_eom_scan_request |
+ * |#CMD_UPHY_PCIE_CONFIG_VDM |#cmd_uphy_pcie_config_vdm_request |
+ * @endcond
*/
-
struct mrq_uphy_request {
/** @brief Lane number. */
uint16_t lane;
- /** @brief Sub-command id. */
+ /** @brief Sub-command ID from @ref mrq_uphy_cmd. */
uint16_t cmd;
union {
@@ -3057,53 +4036,68 @@ struct mrq_uphy_request {
struct cmd_uphy_ep_controller_pll_init_request ep_ctrlr_pll_init;
struct cmd_uphy_pcie_controller_state_request controller_state;
struct cmd_uphy_ep_controller_pll_off_request ep_ctrlr_pll_off;
+ /** @cond bpmp_t238 */
struct cmd_uphy_display_port_init_request display_port_init;
struct cmd_uphy_xusb_dyn_lanes_restore_request xusb_dyn_lanes_restore;
+ /** @endcond */
+ /** @cond bpmp_th500 */
+ struct cmd_uphy_lane_eom_scan_request lane_eom_scan;
+ struct cmd_uphy_pcie_config_vdm_request pcie_vdm;
+ /** @endcond */
} BPMP_UNION_ANON;
} BPMP_ABI_PACKED;
/**
* @ingroup UPHY
- * @brief Response to MRQ_UPHY
+ * @brief Response payload for the #MRQ_UPHY -command.
*
* Each sub-command supported by @ref mrq_uphy_request may return
* sub-command-specific data. Some do and some do not as indicated in
* the following table
*
- * |sub-command |payload |
- * |---------------------------- |------------------------|
- * |CMD_UPHY_PCIE_LANE_MARGIN_CONTROL | |
- * |CMD_UPHY_PCIE_LANE_MARGIN_STATUS |uphy_get_margin_status |
+ * |sub-command |payload |
+ * |-----------------------------------|---------------------------------|
+ * |#CMD_UPHY_PCIE_LANE_MARGIN_CONTROL |- |
+ * |#CMD_UPHY_PCIE_LANE_MARGIN_STATUS |#cmd_uphy_margin_status_response |
*
+ * @cond bpmp_th500
+ * The following additional sub-commands are supported on TH500 platforms:
+ * |sub-command |payload |
+ * |-----------------------------------|---------------------------------|
+ * |#CMD_UPHY_LANE_EOM_SCAN |#cmd_uphy_lane_eom_scan_response |
+ * |#CMD_UPHY_PCIE_CONFIG_VDM |- |
+ * @endcond
*/
-
struct mrq_uphy_response {
union {
struct cmd_uphy_margin_status_response uphy_get_margin_status;
+ /** @cond bpmp_th500 */
+ struct cmd_uphy_lane_eom_scan_response eom_status;
+ /** @endcond */
} BPMP_UNION_ANON;
} BPMP_ABI_PACKED;
/** @} UPHY */
-/** @endcond (bpmp_t194 || bpmp_t234 || bpmp_t239 || bpmp_th500) */
+/** @endcond */
-/**
+/** @cond (bpmp_t194 || bpmp_t234 || bpmp_t238 || bpmp_t264)
* @ingroup MRQ_Codes
* @def MRQ_FMON
- * @brief Perform a frequency monitor configuration operations
+ * @brief Perform a frequency monitor configuration operation
*
- * * Platforms: T194 onwards
- * @cond (bpmp_t194 || bpmp_t234 || bpmp_t239 || bpmp_th500)
* * Initiators: CCPLEX
* * Targets: BPMP
* * Request Payload: @ref mrq_fmon_request
* * Response Payload: @ref mrq_fmon_response
- * @endcond (bpmp_t194 || bpmp_t234 || bpmp_t239 || bpmp_th500)
*
* @addtogroup FMON
* @{
- * @cond (bpmp_t194 || bpmp_t234)
*/
-enum {
+
+/**
+ * @brief Sub-command identifiers for #MRQ_FMON
+ */
+enum mrq_fmon_cmd {
/**
* @brief Clamp FMON configuration to specified rate.
*
@@ -3111,62 +4105,80 @@ enum {
* clamped, FMON configuration is preserved when clock rate
* and/or state is changed.
*
- * mrq_response::err is 0 if the operation was successful, or @n
- * -#BPMP_EACCES: FMON access error @n
- * -#BPMP_EBADCMD if subcommand is not supported @n
- * -#BPMP_EBADSLT: clamp FMON on cluster with auto-CC3 enabled @n
- * -#BPMP_EBUSY: fmon is already clamped at different rate @n
- * -#BPMP_EFAULT: self-diagnostic error @n
- * -#BPMP_EINVAL: invalid FMON configuration @n
- * -#BPMP_EOPNOTSUPP: not in production mode @n
- * -#BPMP_ENODEV: invalid clk_id @n
- * -#BPMP_ENOENT: no calibration data, uninitialized @n
- * -#BPMP_ENOTSUP: avfs config not set @n
- * -#BPMP_ENOSYS: clamp FMON on cluster clock w/ no NAFLL @n
- * -#BPMP_ETIMEDOUT: operation timed out @n
+ * mrq_response::err for this sub-command is defined to be:
+ *
+ * | Value | Description |
+ * |-------------------|---------------------------------------------------|
+ * | 0 | Operation was successful. |
+ * | -#BPMP_EBADCMD | Subcommand is not supported. |
+ * | -#BPMP_EACCES | FMON access error. |
+ * | -#BPMP_EBADSLT | Clamp FMON on cluster with auto-CC3 enabled. |
+ * | -#BPMP_EBUSY | FMON is already clamped at different rate. |
+ * | -#BPMP_EFAULT | Self-diagnostic error detected. |
+ * | -#BPMP_EINVAL | Invalid FMON configuration. |
+ * | -#BPMP_EOPNOTSUPP | Not in production mode. |
+ * | -#BPMP_ENODEV | Invalid clock ID in mrq_fmon_request::cmd_and_id. |
+ * | -#BPMP_ENOENT | No calibration data, uninitialized. |
+ * | -#BPMP_ENOTSUP | AVFS config not set. |
+ * | -#BPMP_ENOSYS | Clamp FMON on cluster clock w/ no NAFLL. |
+ * | -#BPMP_ETIMEDOUT | Operation timed out. |
*/
CMD_FMON_GEAR_CLAMP = 1,
+
/**
* @brief Release clamped FMON configuration.
*
* Allow FMON configuration to follow monitored clock rate
* and/or state changes.
*
- * mrq_response::err is 0 if the operation was successful, or @n
- * -#BPMP_EBADCMD if subcommand is not supported @n
- * -#BPMP_ENODEV: invalid clk_id @n
- * -#BPMP_ENOENT: no calibration data, uninitialized @n
- * -#BPMP_ENOTSUP: avfs config not set @n
- * -#BPMP_EOPNOTSUPP: not in production mode @n
+ * mrq_response::err for this sub-command is defined to be:
+ *
+ * | Value | Description |
+ * |-------------------|---------------------------------------------------|
+ * | 0 | Operation was successful. |
+ * | -#BPMP_EBADCMD | Subcommand is not supported. |
+ * | -#BPMP_ENODEV | Invalid clock ID in mrq_fmon_request::cmd_and_id. |
+ * | -#BPMP_ENOENT | No calibration data, uninitialized. |
+ * | -#BPMP_ENOTSUP | AVFS config not set. |
+ * | -#BPMP_EOPNOTSUPP | Not in production mode. |
*/
CMD_FMON_GEAR_FREE = 2,
+
/**
- * @brief Return rate FMON is clamped at, or 0 if FMON is not
- * clamped.
+ * @brief Return rate FMON is clamped at, or 0 if FMON is not clamped.
*
- * Inherently racy, since clamp state can be changed
- * concurrently. Useful for testing.
+ * Inherently racy, since clamp state can be changed concurrently,
+ * only provided and useful for testing purposes.
*
- * mrq_response::err is 0 if the operation was successful, or @n
- * -#BPMP_EBADCMD if subcommand is not supported @n
- * -#BPMP_ENODEV: invalid clk_id @n
- * -#BPMP_ENOENT: no calibration data, uninitialized @n
- * -#BPMP_ENOTSUP: avfs config not set @n
- * -#BPMP_EOPNOTSUPP: not in production mode @n
+ * mrq_response::err for this sub-command is defined to be:
+ *
+ * | Value | Description |
+ * |-------------------|---------------------------------------------------|
+ * | 0 | Operation was successful. |
+ * | -#BPMP_EBADCMD | Subcommand is not supported. |
+ * | -#BPMP_ENODEV | Invalid clock ID in mrq_fmon_request::cmd_and_id. |
+ * | -#BPMP_ENOENT | No calibration data, uninitialized. |
+ * | -#BPMP_ENOTSUP | AVFS config not set. |
+ * | -#BPMP_EOPNOTSUPP | Not in production mode. |
*/
CMD_FMON_GEAR_GET = 3,
+
/**
* @brief Return current status of FMON faults detected by FMON
- * h/w or s/w since last invocation of this command.
- * Clears fault status.
+ * HW or SW since last invocation of this sub-command.
+ * Clears fault status.
*
- * mrq_response::err is 0 if the operation was successful, or @n
- * -#BPMP_EBADCMD if subcommand is not supported @n
- * -#BPMP_EINVAL: invalid fault type @n
- * -#BPMP_ENODEV: invalid clk_id @n
- * -#BPMP_ENOENT: no calibration data, uninitialized @n
- * -#BPMP_ENOTSUP: avfs config not set @n
- * -#BPMP_EOPNOTSUPP: not in production mode @n
+ * mrq_response::err for this sub-command is defined to be:
+ *
+ * | Value | Description |
+ * |-------------------|---------------------------------------------------|
+ * | 0 | Operation was successful. |
+ * | -#BPMP_EBADCMD | Subcommand is not supported. |
+ * | -#BPMP_ENODEV | Invalid clock ID in mrq_fmon_request::cmd_and_id. |
+ * | -#BPMP_ENOENT | No calibration data, uninitialized. |
+ * | -#BPMP_ENOTSUP | AVFS config not set. |
+ * | -#BPMP_EOPNOTSUPP | Not in production mode. |
+ * | -#BPMP_EINVAL | Invalid fault type. |
*/
CMD_FMON_FAULT_STS_GET = 4,
};
@@ -3177,25 +4189,30 @@ enum {
*/
#define CMD_FMON_NUM 4
-/** @endcond DEPRECATED */
+/** @endcond */
/**
- * @defgroup fmon_fault_type FMON fault type
+ * @defgroup fmon_fault_type FMON fault types
* @addtogroup fmon_fault_type
* @{
*/
-/** @brief All detected FMON faults (h/w or s/w) */
+/** @brief All detected FMON faults (HW or SW) */
#define FMON_FAULT_TYPE_ALL 0U
-/** @brief FMON faults detected by h/w */
+/** @brief FMON faults detected by HW */
#define FMON_FAULT_TYPE_HW 1U
-/** @brief FMON faults detected by s/w */
+/** @brief FMON faults detected by SW */
#define FMON_FAULT_TYPE_SW 2U
/** @} fmon_fault_type */
-
+/**
+ * @brief Request payload for #MRQ_FMON sub-command #CMD_FMON_GEAR_CLAMP.
+ */
struct cmd_fmon_gear_clamp_request {
+ /** @brief Unused / reserved */
int32_t unused;
+
+ /** @brief Target rate in Hz. Valid range for the rate is [1, INT64_MAX] */
int64_t rate;
} BPMP_ABI_PACKED;
@@ -3219,40 +4236,63 @@ struct cmd_fmon_gear_get_request {
BPMP_ABI_EMPTY
} BPMP_ABI_PACKED;
+/**
+ * @brief Response payload for #MRQ_FMON sub-command #CMD_FMON_GEAR_GET.
+ */
struct cmd_fmon_gear_get_response {
int64_t rate;
} BPMP_ABI_PACKED;
+/**
+ * @brief Request payload for #MRQ_FMON sub-command #CMD_FMON_FAULT_STS_GET
+ */
struct cmd_fmon_fault_sts_get_request {
- uint32_t fault_type; /**< @ref fmon_fault_type */
+ /**
+ * @brief Which fault types to return in response:
+ *
+ * | Value | Description |
+ * |----------------------|-----------------------------------------|
+ * | #FMON_FAULT_TYPE_ALL | Return all detected faults (HW and SW). |
+ * | #FMON_FAULT_TYPE_HW | Return only HW detected faults. |
+ * | #FMON_FAULT_TYPE_SW | Return only SW detected faults. |
+ */
+ uint32_t fault_type;
} BPMP_ABI_PACKED;
+/**
+ * @brief Response payload for #MRQ_FMON sub-command #CMD_FMON_FAULT_STS_GET
+ */
struct cmd_fmon_fault_sts_get_response {
+ /**
+ * Bitmask of detected HW / SW specific faults, or 0 if no faults have
+ * been detected since last invocation of #CMD_FMON_FAULT_STS_GET.
+ */
uint32_t fault_sts;
} BPMP_ABI_PACKED;
/**
* @ingroup FMON
- * @brief Request with #MRQ_FMON
+ * @brief Request payload for the #MRQ_FMON -command.
*
* Used by the sender of an #MRQ_FMON message to configure clock
* frequency monitors. The FMON request is split into several
- * sub-commands. Some sub-commands require no additional data.
- * Others have a sub-command specific payload
+ * sub-commands. Sub-command specific payloads are defined in
+ * the following table:
*
- * |sub-command |payload |
- * |----------------------------|-----------------------|
- * |CMD_FMON_GEAR_CLAMP |fmon_gear_clamp |
- * |CMD_FMON_GEAR_FREE |- |
- * |CMD_FMON_GEAR_GET |- |
- * |CMD_FMON_FAULT_STS_GET |fmon_fault_sts_get |
+ * |Sub-command |Payload |
+ * |------------------------|--------------------------------|
+ * |#CMD_FMON_GEAR_CLAMP |#cmd_fmon_gear_clamp_request |
+ * |#CMD_FMON_GEAR_FREE |- |
+ * |#CMD_FMON_GEAR_GET |- |
+ * |#CMD_FMON_FAULT_STS_GET |#cmd_fmon_fault_sts_get_request |
*
*/
struct mrq_fmon_request {
- /** @brief Sub-command and clock id concatenated to 32-bit word.
- * - bits[31..24] is the sub-cmd.
- * - bits[23..0] is monitored clock id used to select target
- * FMON
+ /**
+ * @brief Sub-command and clock id concatenated to 32-bit word.
+ *
+ * - bits[31..24] -> Sub-command identifier from @ref mrq_fmon_cmd.
+ * - bits[23..0] -> Monitored clock identifier used to select target FMON.
*/
uint32_t cmd_and_id;
@@ -3268,20 +4308,19 @@ struct mrq_fmon_request {
/**
* @ingroup FMON
- * @brief Response to MRQ_FMON
+ * @brief Response payload for the #MRQ_FMON -command.
*
* Each sub-command supported by @ref mrq_fmon_request may
* return sub-command-specific data as indicated below.
*
- * |sub-command |payload |
- * |----------------------------|------------------------|
- * |CMD_FMON_GEAR_CLAMP |- |
- * |CMD_FMON_GEAR_FREE |- |
- * |CMD_FMON_GEAR_GET |fmon_gear_get |
- * |CMD_FMON_FAULT_STS_GET |fmon_fault_sts_get |
+ * |Sub-command |Payload |
+ * |------------------------|---------------------------------|
+ * |#CMD_FMON_GEAR_CLAMP |- |
+ * |#CMD_FMON_GEAR_FREE |- |
+ * |#CMD_FMON_GEAR_GET |#cmd_fmon_gear_get_response |
+ * |#CMD_FMON_FAULT_STS_GET |#cmd_fmon_fault_sts_get_response |
*
*/
-
struct mrq_fmon_response {
union {
/** @private */
@@ -3293,17 +4332,15 @@ struct mrq_fmon_response {
} BPMP_UNION_ANON;
} BPMP_ABI_PACKED;
-/** @endcond (bpmp_t194 || bpmp_t234) */
/** @} FMON */
+/** @endcond */
-/**
+/** @cond (bpmp_t194)
* @ingroup MRQ_Codes
* @def MRQ_EC
* @brief Provide status information on faults reported by Error
* Collator (EC) to HSM.
*
- * * Platforms: T194
- * @cond bpmp_t194
* * Initiators: CCPLEX
* * Targets: BPMP
* * Request Payload: @ref mrq_ec_request
@@ -3311,10 +4348,8 @@ struct mrq_fmon_response {
*
* @note This MRQ ABI is under construction, and subject to change
*
- * @endcond bpmp_t194
* @addtogroup EC
* @{
- * @cond bpmp_t194
*/
enum {
/**
@@ -3325,7 +4360,7 @@ enum {
* -#BPMP_ENODEV if target EC is not owned by BPMP @n
* -#BPMP_EACCES if target EC power domain is turned off @n
* -#BPMP_EBADCMD if subcommand is not supported
- * @endcond DEPRECATED
+ * @endcond
*/
CMD_EC_STATUS_GET = 1, /* deprecated */
@@ -3572,7 +4607,7 @@ struct cmd_ec_status_get_response {
/** @brief EC error descriptors */
union ec_err_desc error_descs[EC_ERR_STATUS_DESC_MAX_NUM];
} BPMP_ABI_PACKED;
-/** @endcond DEPRECATED */
+/** @endcond */
struct cmd_ec_status_ex_get_response {
/** @brief Target EC id (the same id received with request). */
@@ -3610,7 +4645,7 @@ struct cmd_ec_status_ex_get_response {
* |sub-command |payload |
* |----------------------------|-----------------------|
* |@ref CMD_EC_STATUS_GET |ec_status_get |
- * @endcond DEPRECATED
+ * @endcond
*
* |sub-command |payload |
* |----------------------------|-----------------------|
@@ -3638,7 +4673,7 @@ struct mrq_ec_request {
* |sub-command |payload |
* |----------------------------|------------------------|
* |@ref CMD_EC_STATUS_GET |ec_status_get |
- * @endcond DEPRECATED
+ * @endcond
*
* |sub-command |payload |
* |----------------------------|------------------------|
@@ -3652,22 +4687,20 @@ struct mrq_ec_response {
* @cond DEPRECATED
*/
struct cmd_ec_status_get_response ec_status_get;
- /** @endcond DEPRECATED */
+ /** @endcond */
struct cmd_ec_status_ex_get_response ec_status_ex_get;
} BPMP_UNION_ANON;
} BPMP_ABI_PACKED;
-/** @endcond bpmp_t194 */
/** @} EC */
+/** @endcond */
-/**
+/** @cond (bpmp_th500)
* @ingroup MRQ_Codes
* @def MRQ_TELEMETRY
* @brief Get address of memory buffer refreshed with recently sampled
* telemetry data
*
- * * Platforms: TH500 onwards
- * @cond bpmp_th500
* * Initiators: CCPLEX
* * Targets: BPMP
* * Request Payload: N/A
@@ -3677,14 +4710,17 @@ struct mrq_ec_response {
*/
/**
- * @brief Response to #MRQ_TELEMETRY
+ * @brief Response payload for the #MRQ_TELEMETRY -command
*
- * mrq_response::err is
- * * 0: Telemetry data is available at returned address
- * * -#BPMP_EACCES: MRQ master is not allowed to request buffer refresh
- * * -#BPMP_ENAVAIL: Telemetry buffer cannot be refreshed via this MRQ channel
- * * -#BPMP_ENOTSUP: Telemetry buffer is not supported by BPMP-FW
- * * -#BPMP_ENODEV: Telemetry mrq is not supported by BPMP-FW
+ * mrq_response::err is defined as:
+ *
+ * | Value | Description |
+ * |-----------------|------------------------------------------------------------|
+ * | 0 | Telemetry data is available at returned address. |
+ * | -#BPMP_EACCES | MRQ master is not allowed to request buffer refresh. |
+ * | -#BPMP_ENAVAIL | Telemetry buffer cannot be refreshed via this MRQ channel. |
+ * | -#BPMP_ENOTSUP | Telemetry buffer is not supported by BPMP-FW. |
+ * | -#BPMP_ENODEV | Telemetry MRQ is not supported by BPMP-FW. |
*/
struct mrq_telemetry_response {
/** @brief Physical address of telemetry data buffer */
@@ -3692,15 +4728,112 @@ struct mrq_telemetry_response {
} BPMP_ABI_PACKED;
/** @} Telemetry */
-/** @endcond bpmp_th500 */
+/** @endcond */
+
+/** @cond (bpmp_tb500)
+ * @ingroup MRQ_Codes
+ * @def MRQ_TELEMETRY_EX
+ * @brief Get telemetry configuration settings.
+ *
+ * * Initiators: Any
+ * * Targets: BPMP
+ * * Request Payload: @ref mrq_telemetry_ex_request
+ * * Response Payload: @ref mrq_telemetry_ex_response
+ *
+ * @addtogroup Telemetry_ex
+ * @{
+ */
/**
+ * @brief Sub-command identifiers for #MRQ_TELEMETRY_EX.
+ */
+enum mrq_telemetry_ex_cmd {
+ /**
+ * @brief Check whether the BPMP-FW supports the specified
+ * #MRQ_TELEMETRY_EX sub-command.
+ *
+ * mrq_response::err is 0 if the specified request is
+ * supported and -#BPMP_ENODEV otherwise.
+ */
+ CMD_TELEMETRY_EX_QUERY_ABI = 0,
+
+ /**
+ * @brief Get telemetry buffer base address and data size
+ *
+ * mrq_response:err is defined as:
+ *
+ * | Value | Description |
+ * |----------------|------------------------------------------------|
+ * | 0 | Success |
+ * | -#BPMP_ENODEV | #MRQ_TELEMETRY_EX is not supported by BPMP-FW. |
+ */
+ CMD_TELEMETRY_EX_BASE_SZ_GET = 1,
+};
+
+/**
+ * @brief Request data for #MRQ_TELEMETRY_EX sub-command
+ * #CMD_TELEMETRY_EX_QUERY_ABI
+ */
+struct cmd_telemetry_ex_query_abi_request {
+ /** @brief Sub-command identifier from @ref mrq_telemetry_ex_cmd */
+ uint32_t cmd_code;
+} BPMP_ABI_PACKED;
+
+/**
+ * @brief Response payload for #MRQ_TELEMETRY_EX sub-command
+ * #CMD_TELEMETRY_EX_BASE_SZ_GET
+ */
+struct cmd_telemetry_ex_base_sz_get_response {
+ /**
+ * @brief Physical address of telemetry data buffer
+ *
+ * 0 if no buffer is allocated for the initiator sending MRQ.
+ */
+ uint64_t buf_base_addr;
+ /** @brief Telemetry data size in bytes */
+ uint32_t buf_size;
+} BPMP_ABI_PACKED;
+
+/**
+ * @brief Request payload for the #MRQ_TELEMETRY_EX -command
+ *
+ * | Sub-command | Request payload |
+ * |-------------------------------|----------------------------------------|
+ * | #CMD_TELEMETRY_EX_QUERY_ABI | #cmd_telemetry_ex_query_abi_request |
+ * | #CMD_TELEMETRY_EX_BASE_SZ_GET | - |
+ */
+struct mrq_telemetry_ex_request {
+ /** @brief Sub-command ID from @ref mrq_telemetry_ex_cmd. */
+ uint32_t cmd;
+ union {
+ struct cmd_telemetry_ex_query_abi_request
+ telemetry_ex_query_abi_req;
+ } BPMP_UNION_ANON;
+} BPMP_ABI_PACKED;
+
+/**
+ * @brief Response payload for the #MRQ_TELEMETRY_EX -command.
+ *
+ * | Sub-command | Response payload |
+ * |-------------------------------|----------------------------------------|
+ * | #CMD_TELEMETRY_EX_QUERY_ABI | - |
+ * | #CMD_TELEMETRY_EX_BASE_SZ_GET | #cmd_telemetry_ex_base_sz_get_response |
+ */
+struct mrq_telemetry_ex_response {
+ union {
+ struct cmd_telemetry_ex_base_sz_get_response
+ telemetry_ex_base_sz_get_rsp;
+ } BPMP_UNION_ANON;
+} BPMP_ABI_PACKED;
+
+/** @} Telemetry_ex */
+/** @endcond */
+
+/** @cond (bpmp_th500 || bpmp_tb500)
* @ingroup MRQ_Codes
* @def MRQ_PWR_LIMIT
* @brief Control power limits.
*
- * * Platforms: TH500 onwards
- * @cond bpmp_th500
* * Initiators: Any
* * Targets: BPMP
* * Request Payload: @ref mrq_pwr_limit_request
@@ -3709,10 +4842,14 @@ struct mrq_telemetry_response {
* @addtogroup Pwrlimit
* @{
*/
+
+/**
+ * @brief Sub-command identifiers for #MRQ_PWR_LIMIT.
+ */
enum mrq_pwr_limit_cmd {
/**
* @brief Check whether the BPMP-FW supports the specified
- * command
+ * #MRQ_PWR_LIMIT sub-command.
*
* mrq_response::err is 0 if the specified request is
* supported and -#BPMP_ENODEV otherwise.
@@ -3722,31 +4859,43 @@ enum mrq_pwr_limit_cmd {
/**
* @brief Set power limit
*
- * mrq_response:err is
- * * 0: Success
- * * -#BPMP_ENODEV: Pwr limit mrq is not supported by BPMP-FW
- * * -#BPMP_ENAVAIL: Invalid request parameters
- * * -#BPMP_EACCES: Request is not accepted
+ * mrq_response:err is defined as:
+ *
+ * | Value | Description |
+ * |----------------|---------------------------------------------|
+ * | 0 | Success |
+ * | -#BPMP_ENODEV | #MRQ_PWR_LIMIT is not supported by BPMP-FW. |
+ * | -#BPMP_EINVAL | Invalid request parameters. |
+ * | -#BPMP_EACCES | Request is not accepted. |
*/
CMD_PWR_LIMIT_SET = 1,
/**
* @brief Get power limit setting
*
- * mrq_response:err is
- * * 0: Success
- * * -#BPMP_ENODEV: Pwr limit mrq is not supported by BPMP-FW
- * * -#BPMP_ENAVAIL: Invalid request parameters
+ * mrq_response:err is defined as:
+ *
+ * | Value | Description |
+ * |----------------|---------------------------------------------|
+ * | 0 | Success |
+ * | -#BPMP_ENODEV | #MRQ_PWR_LIMIT is not supported by BPMP-FW. |
+ * | -#BPMP_EINVAL | Invalid request parameters. |
*/
CMD_PWR_LIMIT_GET = 2,
/**
- * @brief Get current power cap
+ * @brief Get current aggregated power cap
*
- * mrq_response:err is
- * * 0: Success
- * * -#BPMP_ENODEV: Pwr limit mrq is not supported by BPMP-FW
- * * -#BPMP_ENAVAIL: Invalid request parameters
+ * Get currently applied power cap for the specified limit id
+ * aggregated across all limit sources and types.
+ *
+ * mrq_response:err is defined as:
+ *
+ * | Value | Description |
+ * |----------------|---------------------------------------------|
+ * | 0 | Success |
+ * | -#BPMP_ENODEV | #MRQ_PWR_LIMIT is not supported by BPMP-FW. |
+ * | -#BPMP_EINVAL | Invalid request parameters. |
*/
CMD_PWR_LIMIT_CURR_CAP = 3,
};
@@ -3761,7 +4910,7 @@ enum mrq_pwr_limit_cmd {
#define PWR_LIMIT_TYPE_BOUND_MAX 1U
/** @brief Limit value specifies minimum possible target cap */
#define PWR_LIMIT_TYPE_BOUND_MIN 2U
-/** @brief Number of limit types supported by mrq interface */
+/** @brief Number of limit types supported by #MRQ_PWR_LIMIT command */
#define PWR_LIMIT_TYPE_NUM 3U
/** @} bpmp_pwr_limit_type */
@@ -3770,7 +4919,8 @@ enum mrq_pwr_limit_cmd {
* @brief Request data for #MRQ_PWR_LIMIT command CMD_PWR_LIMIT_QUERY_ABI
*/
struct cmd_pwr_limit_query_abi_request {
- uint32_t cmd_code; /**< @ref mrq_pwr_limit_cmd */
+ /** @brief Sub-command identifier from @ref mrq_pwr_limit_cmd */
+ uint32_t cmd_code;
} BPMP_ABI_PACKED;
/**
@@ -3782,56 +4932,66 @@ struct cmd_pwr_limit_query_abi_request {
* is ignored by the arbitration (i.e., indicates "no limit set").
*/
struct cmd_pwr_limit_set_request {
- uint32_t limit_id; /**< @ref bpmp_pwr_limit_id */
+ /** @brief Power limit identifier from @ref bpmp_pwr_limit_id */
+ uint32_t limit_id;
+ /** @brief Power limit source identifier from @ref bpmp_pwr_limit_src */
uint32_t limit_src; /**< @ref bpmp_pwr_limit_src */
- uint32_t limit_type; /**< @ref bpmp_pwr_limit_type */
+ /** @brief Power limit type from @ref bpmp_pwr_limit_type */
+ uint32_t limit_type;
+ /** @brief New power limit value */
uint32_t limit_setting;
} BPMP_ABI_PACKED;
/**
- * @brief Request data for #MRQ_PWR_LIMIT command CMD_PWR_LIMIT_GET
+ * @brief Request payload for #MRQ_PWR_LIMIT sub-command #CMD_PWR_LIMIT_GET
*
* Get previously set from specified source specified limit value of specified
* type.
*/
struct cmd_pwr_limit_get_request {
- uint32_t limit_id; /**< @ref bpmp_pwr_limit_id */
+ /** @brief Power limit identifier from @ref bpmp_pwr_limit_id */
+ uint32_t limit_id;
+ /** @brief Power limit source identifier from @ref bpmp_pwr_limit_src */
uint32_t limit_src; /**< @ref bpmp_pwr_limit_src */
- uint32_t limit_type; /**< @ref bpmp_pwr_limit_type */
+ /** @brief Power limit type from @ref bpmp_pwr_limit_type */
+ uint32_t limit_type;
} BPMP_ABI_PACKED;
/**
- * @brief Response data for #MRQ_PWR_LIMIT command CMD_PWR_LIMIT_GET
+ * @brief Response payload for #MRQ_PWR_LIMIT sub-command #CMD_PWR_LIMIT_GET
*/
struct cmd_pwr_limit_get_response {
+ /** @brief Power limit value */
uint32_t limit_setting;
} BPMP_ABI_PACKED;
/**
- * @brief Request data for #MRQ_PWR_LIMIT command CMD_PWR_LIMIT_CURR_CAP
+ * @brief Request payload for #MRQ_PWR_LIMIT sub-command #CMD_PWR_LIMIT_CURR_CAP
*
* For specified limit get current power cap aggregated from all sources.
*/
struct cmd_pwr_limit_curr_cap_request {
- uint32_t limit_id; /**< @ref bpmp_pwr_limit_id */
+ /** @brief Power limit identifier from @ref bpmp_pwr_limit_id */
+ uint32_t limit_id;
} BPMP_ABI_PACKED;
/**
- * @brief Response data for #MRQ_PWR_LIMIT command CMD_PWR_LIMIT_CURR_CAP
+ * @brief Response payload for #MRQ_PWR_LIMIT sub-command #CMD_PWR_LIMIT_CURR_CAP
*/
struct cmd_pwr_limit_curr_cap_response {
+ /** @brief Current power cap value */
uint32_t curr_cap;
} BPMP_ABI_PACKED;
/**
- * @brief Request with #MRQ_PWR_LIMIT
+ * @brief Request payload for the #MRQ_PWR_LIMIT -command
*
- * |sub-command |payload |
- * |----------------------------|---------------------------------|
- * |CMD_PWR_LIMIT_QUERY_ABI | cmd_pwr_limit_query_abi_request |
- * |CMD_PWR_LIMIT_SET | cmd_pwr_limit_set_request |
- * |CMD_PWR_LIMIT_GET | cmd_pwr_limit_get_request |
- * |CMD_PWR_LIMIT_CURR_CAP | cmd_pwr_limit_curr_cap_request |
+ * | Sub-command | Request payload |
+ * |--------------------------|----------------------------------|
+ * | #CMD_PWR_LIMIT_QUERY_ABI | #cmd_pwr_limit_query_abi_request |
+ * | #CMD_PWR_LIMIT_SET | #cmd_pwr_limit_set_request |
+ * | #CMD_PWR_LIMIT_GET | #cmd_pwr_limit_get_request |
+ * | #CMD_PWR_LIMIT_CURR_CAP | #cmd_pwr_limit_curr_cap_request |
*/
struct mrq_pwr_limit_request {
uint32_t cmd;
@@ -3844,14 +5004,14 @@ struct mrq_pwr_limit_request {
} BPMP_ABI_PACKED;
/**
- * @brief Response to MRQ_PWR_LIMIT
+ * @brief Response payload for the #MRQ_PWR_LIMIT -command.
*
- * |sub-command |payload |
- * |----------------------------|---------------------------------|
- * |CMD_PWR_LIMIT_QUERY_ABI | - |
- * |CMD_PWR_LIMIT_SET | - |
- * |CMD_PWR_LIMIT_GET | cmd_pwr_limit_get_response |
- * |CMD_PWR_LIMIT_CURR_CAP | cmd_pwr_limit_curr_cap_response |
+ * | Sub-command | Response payload |
+ * |--------------------------|----------------------------------|
+ * | #CMD_PWR_LIMIT_QUERY_ABI | - |
+ * | #CMD_PWR_LIMIT_SET | - |
+ * | #CMD_PWR_LIMIT_GET | #cmd_pwr_limit_get_response |
+ * | #CMD_PWR_LIMIT_CURR_CAP | #cmd_pwr_limit_curr_cap_response |
*/
struct mrq_pwr_limit_response {
union {
@@ -3860,17 +5020,395 @@ struct mrq_pwr_limit_response {
} BPMP_UNION_ANON;
} BPMP_ABI_PACKED;
-/** @} PwrLimit */
-/** @endcond bpmp_th500 */
+/** @} Pwrlimit */
+/** @endcond */
+
+
+
+/** @cond (bpmp_th500)
+ * @ingroup MRQ_Codes
+ * @def MRQ_PWRMODEL
+ * @brief Retrieve power evaluted by SoC power model.
+ *
+ * * Initiators: Any
+ * * Targets: BPMP
+ * * Request Payload: @ref mrq_pwrmodel_request
+ * * Response Payload: @ref mrq_pwrmodel_response
+ *
+ * @addtogroup Pwrmodel
+ * @{
+ */
+
+/**
+ * @brief Sub-command identifiers for #MRQ_PWRMODEL.
+ */
+enum mrq_pwrmodel_cmd {
+ /**
+ * @brief Check whether the BPMP-FW supports the specified
+ * #MRQ_PWRMODEL sub-command.
+ *
+ * mrq_response::err is 0 if the specified request is
+ * supported and -#BPMP_ENODEV otherwise.
+ */
+ CMD_PWRMODEL_QUERY_ABI = 0,
+
+ /**
+ * @brief Get power model output power
+ *
+ * mrq_response:err is defined as:
+ *
+ * | Value | Description |
+ * |----------------|---------------------------------------------|
+ * | 0 | Success |
+ * | -#BPMP_ENODEV | #MRQ_PWRMODEL is not supported by BPMP-FW. |
+ * | -#BPMP_ERANGE | Power model calculation overflow. |
+ */
+ CMD_PWRMODEL_PWR_GET = 1,
+};
+
+/**
+ * @brief Request data for #MRQ_PWRMODEL sub-command #CMD_PWRMODEL_QUERY_ABI
+ */
+struct cmd_pwrmodel_query_abi_request {
+ /** @brief Sub-command identifier from @ref mrq_pwrmodel_cmd */
+ uint32_t cmd_code;
+} BPMP_ABI_PACKED;
+
+/**
+ * @brief Request payload for #MRQ_PWRMODEL sub-command #CMD_PWRMODEL_PWR_GET
+ *
+ * Rerieve power evaluated by power model for specified work-load factor,
+ * temperature, and cpu iso frequency for all cores.
+ */
+struct cmd_pwrmodel_pwr_get_request {
+ /** @brief Unitless work load factor to evaluate power model at */
+ uint32_t work_load_factor;
+ /** @brief CPU frequency in kHz to evaluate power model at */
+ uint32_t cpu_frequency;
+ /** @brief Temperature in mC to evaluate power model at */
+ int32_t temperature;
+} BPMP_ABI_PACKED;
+
+/**
+ * @brief Response payload for #MRQ_PWRMODEL sub-command #CMD_PWRMODEL_PWR_GET
+ */
+struct cmd_pwrmodel_pwr_get_response {
+ /** @brief Power model output in mW */
+ uint32_t power;
+} BPMP_ABI_PACKED;
+/**
+ * @brief Request payload for the #MRQ_PWRMODEL -command
+ *
+ * | Sub-command | Request payload |
+ * |--------------------------|----------------------------------|
+ * | #CMD_PWRMODEL_QUERY_ABI | #cmd_pwrmodel_query_abi_request |
+ * | #CMD_PWRMODEL_PWR_GET | #cmd_pwrmodel_pwr_get_request |
+ */
+struct mrq_pwrmodel_request {
+ uint32_t cmd;
+ union {
+ struct cmd_pwrmodel_query_abi_request pwrmodel_query_abi_req;
+ struct cmd_pwrmodel_pwr_get_request pwrmodel_pwr_get_req;
+ } BPMP_UNION_ANON;
+} BPMP_ABI_PACKED;
/**
+ * @brief Response payload for the #MRQ_PWRMODEL -command.
+ *
+ * | Sub-command | Response payload |
+ * |--------------------------|----------------------------------|
+ * | #CMD_PWRMODEL_QUERY_ABI | - |
+ * | #CMD_PWRMODEL_PWR_GET | #cmd_pwrmodel_pwr_get_response |
+ */
+struct mrq_pwrmodel_response {
+ union {
+ struct cmd_pwrmodel_pwr_get_response pwrmodel_pwr_get_rsp;
+ } BPMP_UNION_ANON;
+} BPMP_ABI_PACKED;
+
+/** @} Pwrmodel */
+/** @endcond */
+
+
+/** @cond (bpmp_th500)
+ * @ingroup MRQ_Codes
+ * @def MRQ_PWR_CNTRL
+ * @brief Configure power controllers.
+ *
+ * * Initiators: Any
+ * * Targets: BPMP
+ * * Request Payload: @ref mrq_pwr_cntrl_request
+ * * Response Payload: @ref mrq_pwr_cntrl_response
+ *
+ * @addtogroup Pwrcntrl
+ * @{
+ */
+
+/**
+ * @brief Sub-command identifiers for #MRQ_PWR_CNTRL.
+ */
+enum mrq_pwr_cntrl_cmd {
+ /**
+ * @brief Check whether the BPMP-FW supports the specified
+ * #MRQ_PWR_CNTRL sub-command.
+ *
+ * mrq_response::err is 0 if the specified request is
+ * supported and -#BPMP_ENODEV otherwise.
+ */
+ CMD_PWR_CNTRL_QUERY_ABI = 0,
+
+ /**
+ * @brief Switch power controller to/out of bypass mode
+ *
+ * mrq_response:err is defined as:
+ *
+ * | Value | Description |
+ * |----------------|---------------------------------------------|
+ * | 0 | Success |
+ * | -#BPMP_ENODEV | #MRQ_PWR_CNTRL is not supported by BPMP-FW. |
+ * | -#BPMP_EINVAL | Invalid request parameters. |
+ * | -#BPMP_ENOTSUP | Bypass mode is not supported. |
+ */
+ CMD_PWR_CNTRL_BYPASS_SET = 1,
+
+ /**
+ * @brief Get power controller bypass mode status
+ *
+ * mrq_response:err is defined as:
+ *
+ * | Value | Description |
+ * |----------------|---------------------------------------------|
+ * | 0 | Success |
+ * | -#BPMP_ENODEV | #MRQ_PWR_CNTRL is not supported by BPMP-FW. |
+ * | -#BPMP_EINVAL | Invalid request parameters. |
+ */
+ CMD_PWR_CNTRL_BYPASS_GET = 2,
+};
+
+/**
+ * @brief Request data for #MRQ_PWR_CNTRL sub-command #CMD_PWR_CNTRL_QUERY_ABI
+ */
+struct cmd_pwr_cntrl_query_abi_request {
+ /** @brief Sub-command identifier from @ref mrq_pwr_cntrl_cmd */
+ uint32_t cmd_code;
+} BPMP_ABI_PACKED;
+
+/**
+ * @brief Request data for #MRQ_PWR_CNTRL sub-command #CMD_PWR_CNTRL_BYPASS_SET
+ *
+ * Switch specified power controller to / out of bypass mode provided such
+ * mode is supported by the controller.
+ */
+struct cmd_pwr_cntrl_bypass_set_request {
+ /** @brief Power controller identifier from @ref bpmp_pwr_cntrl_id */
+ uint32_t cntrl_id;
+ /**
+ * @brief Bypass setting.
+ *
+ * Valid values:
+ *
+ * * 1 to enter bypass mode,
+ * * 0 to exit bypass mode.
+ */
+ uint32_t bypass_setting;
+} BPMP_ABI_PACKED;
+
+/**
+ * @brief Request data for #MRQ_PWR_CNTRL sub-command #CMD_PWR_CNTRL_BYPASS_GET
+ *
+ * Get bypass mode status of the specified power controller.
+ */
+struct cmd_pwr_cntrl_bypass_get_request {
+ /** @brief Power controller identifier from @ref bpmp_pwr_cntrl_id */
+ uint32_t cntrl_id;
+} BPMP_ABI_PACKED;
+
+/**
+ * @brief Response data for #MRQ_PWR_CNTRL sub-command #CMD_PWR_CNTRL_BYPASS_GET
+ *
+ * Get current bypass mode status if such mode is supported by the controller.
+ * Otherwise, return "out of bypass" .
+ */
+struct cmd_pwr_cntrl_bypass_get_response {
+ /**
+ * @brief Bypass mode status: 1 controller is in bypass,
+ * 0 controller is out of bypass.
+ */
+ uint32_t bypass_status;
+} BPMP_ABI_PACKED;
+
+/**
+ * @brief Request payload for the #MRQ_PWR_CNTRL -command
+ *
+ * | Sub-command | Request payload |
+ * |---------------------------|-----------------------------------|
+ * | #CMD_PWR_CNTRL_QUERY_ABI | #cmd_pwr_cntrl_query_abi_request |
+ * | #CMD_PWR_CNTRL_BYPASS_SET | #cmd_pwr_cntrl_bypass_set_request |
+ * | #CMD_PWR_CNTRL_BYPASS_GET | #cmd_pwr_cntrl_bypass_get_request |
+ */
+struct mrq_pwr_cntrl_request {
+ uint32_t cmd;
+ union {
+ struct cmd_pwr_cntrl_query_abi_request pwr_cntrl_query_abi_req;
+ struct cmd_pwr_cntrl_bypass_set_request pwr_cntrl_bypass_set_req;
+ struct cmd_pwr_cntrl_bypass_get_request pwr_cntrl_bypass_get_req;
+ } BPMP_UNION_ANON;
+} BPMP_ABI_PACKED;
+
+/**
+ * @brief Response payload for the #MRQ_PWR_CNTRL -command.
+ *
+ * | Sub-command | Response payload |
+ * |---------------------------|-----------------------------------|
+ * | #CMD_PWR_CNTRL_QUERY_ABI | - |
+ * | #CMD_PWR_CNTRL_BYPASS_SET | - |
+ * | #CMD_PWR_CNTRL_BYPASS_GET | #cmd_pwr_cntrl_bypass_get_response|
+ */
+struct mrq_pwr_cntrl_response {
+ union {
+ struct cmd_pwr_cntrl_bypass_get_response pwr_cntrl_bypass_get_rsp;
+ } BPMP_UNION_ANON;
+} BPMP_ABI_PACKED;
+
+/** @} Pwrcntrl */
+/** @endcond */
+
+
+/** @cond (bpmp_t264)
+ * @ingroup MRQ_Codes
+ * @def MRQ_SLC
+ * @brief Configure SLC state.
+ *
+ * * Initiators: Any
+ * * Targets: BPMP
+ * * Request Payload: @ref mrq_slc_request
+ * * Response Payload: @ref mrq_slc_response
+ *
+ * @addtogroup Slc
+ * @{
+ */
+
+/**
+ * @brief Sub-command identifiers for #MRQ_SLC.
+ */
+enum mrq_slc_cmd {
+ /**
+ * @brief Check whether the BPMP-FW supports the specified
+ * #MRQ_SLC sub-command.
+ *
+ * mrq_response::err is 0 if the specified request is
+ * supported and -#BPMP_ENODEV otherwise.
+ */
+ CMD_SLC_QUERY_ABI = 0,
+
+ /**
+ * @brief Switch SLC to/out of bypass mode
+ *
+ * mrq_response:err is defined as:
+ *
+ * | Value | Description |
+ * |----------------|---------------------------------------------|
+ * | 0 | Success |
+ * | -#BPMP_ENODEV | #MRQ_SLC is not supported by BPMP-FW. |
+ * | -#BPMP_EINVAL | Invalid request parameters. |
+ * | -#BPMP_ENOTSUP | Bypass mode is not supported. |
+ */
+ CMD_SLC_BYPASS_SET = 1,
+
+ /**
+ * @brief Get SLC bypass mode status
+ *
+ * mrq_response:err is defined as:
+ *
+ * | Value | Description |
+ * |----------------|---------------------------------------------|
+ * | 0 | Success |
+ * | -#BPMP_ENODEV | #MRQ_SLC is not supported by BPMP-FW. |
+ */
+ CMD_SLC_BYPASS_GET = 2,
+};
+
+/**
+ * @brief Request data for #MRQ_SLC sub-command #CMD_SLC_QUERY_ABI
+ */
+struct cmd_slc_query_abi_request {
+ /** @brief Sub-command identifier from @ref mrq_slc_cmd */
+ uint32_t cmd_code;
+} BPMP_ABI_PACKED;
+
+/**
+ * @brief Request data for #MRQ_SLC sub-command #CMD_SLC_BYPASS_SET
+ *
+ * Switch SLC to / out of bypass mode provided such
+ * mode is supported by the SLC.
+ */
+struct cmd_slc_bypass_set_request {
+ /**
+ * @brief Bypass setting.
+ *
+ * Valid values:
+ *
+ * * 1 to enter bypass mode,
+ * * 0 to exit bypass mode.
+ */
+ uint32_t bypass_setting;
+} BPMP_ABI_PACKED;
+
+/**
+ * @brief Response data for #MRQ_SLC sub-command #CMD_SLC_BYPASS_GET
+ *
+ * Get current bypass mode status if such mode is supported by the SLC.
+ * Otherwise, return "out of bypass" .
+ */
+struct cmd_slc_bypass_get_response {
+ /**
+ * @brief Bypass mode status: 1 SLC is in bypass,
+ * 0 SLC is out of bypass.
+ */
+ uint32_t bypass_status;
+} BPMP_ABI_PACKED;
+
+/**
+ * @brief Request payload for the #MRQ_SLC -command
+ *
+ * | Sub-command | Request payload |
+ * |---------------------------|-----------------------------------|
+ * | #CMD_SLC_QUERY_ABI | #cmd_slc_query_abi_request |
+ * | #CMD_SLC_BYPASS_SET | #cmd_slc_bypass_set_request |
+ * | #CMD_SLC_BYPASS_GET | - |
+ */
+struct mrq_slc_request {
+ uint32_t cmd;
+ union {
+ struct cmd_slc_query_abi_request slc_query_abi_req;
+ struct cmd_slc_bypass_set_request slc_bypass_set_req;
+ } BPMP_UNION_ANON;
+} BPMP_ABI_PACKED;
+
+/**
+ * @brief Response payload for the #MRQ_SLC -command.
+ *
+ * | Sub-command | Response payload |
+ * |---------------------------|-----------------------------------|
+ * | #CMD_SLC_QUERY_ABI | - |
+ * | #CMD_SLC_BYPASS_SET | - |
+ * | #CMD_SLC_BYPASS_GET | #cmd_slc_bypass_get_response |
+ */
+struct mrq_slc_response {
+ union {
+ struct cmd_slc_bypass_get_response slc_bypass_get_rsp;
+ } BPMP_UNION_ANON;
+} BPMP_ABI_PACKED;
+
+/** @} Slc */
+/** @endcond */
+
+/** @cond (bpmp_th500)
* @ingroup MRQ_Codes
* @def MRQ_GEARS
* @brief Get thresholds for NDIV offset switching
*
- * * Platforms: TH500 onwards
- * @cond bpmp_th500
* * Initiators: CCPLEX
* * Targets: BPMP
* * Request Payload: N/A
@@ -3905,11 +5443,1248 @@ struct mrq_pwr_limit_response {
*/
struct mrq_gears_response {
/** @brief number of online CPUs for each gear */
- uint32_t ncpu[16];
+ uint32_t ncpu[8];
+ /** @brief ndiv offset for each gear */
+ uint32_t ndiv_offset[8];
+ /** @brief voltage below which gears are disabled */
+ uint32_t uv_threshold;
} BPMP_ABI_PACKED;
/** @} Gears */
-/** @endcond bpmp_th500 */
+/** @endcond */
+
+
+/**
+ * @ingroup MRQ_Codes
+ * @def MRQ_SHUTDOWN
+ * @brief System shutdown
+ *
+ * This message indicates system shutdown or reboot request. BPMP will
+ * initiate system shutdown/reboot after receiving this message, it
+ * may include turning off some rails in sequence and programming
+ * PMIC.
+ *
+ * * Initiators: CPU_S, MCE
+ * * Targets: BPMP
+ * * Request Payload: @ref mrq_shutdown_request
+ * * Response Payload: N/A
+ * @addtogroup Shutdown
+ * @{
+ */
+
+/**
+ * @brief Request with #MRQ_SHUTDOWN
+ */
+struct mrq_shutdown_request {
+ /**
+ * @brief Shutdown state ID
+ *
+ * Legal values:
+ * * 0 - Power off
+ * * 1 - Reboot
+ * @cond bpmp_t264
+ * * 2 - Suspend
+ * @endcond
+ */
+ uint32_t state;
+} BPMP_ABI_PACKED;
+
+/** @} Shutdown */
+
+/** @cond (bpmp_th500 || bpmp_tb500)
+ * @defgroup bpmp_c2c_status C2C link status
+ * @addtogroup bpmp_c2c_status
+ * @{
+ */
+/** @brief initial status code */
+#define BPMP_C2C_STATUS_INIT_NOT_STARTED 0
+/** @brief Invalid speedo code */
+#define BPMP_C2C_STATUS_C2C_INVALID_SPEEDO_CODE 7
+/** @brief Invalid frequency */
+#define BPMP_C2C_STATUS_C2C_INVALID_FREQ 8
+/** @brief Invalid link */
+#define BPMP_C2C_STATUS_C2C_INVALID_LINK 9
+/** @brief refpll lock polling times out - partition 0 */
+#define BPMP_C2C_STATUS_C2C0_REFPLL_FAIL 10
+/** @brief refpll lock polling times out - partition 1 */
+#define BPMP_C2C_STATUS_C2C1_REFPLL_FAIL 11
+/** @brief PLL cal times out - partition 0 */
+#define BPMP_C2C_STATUS_C2C0_PLLCAL_FAIL 12
+/** @brief PLL cal times out - partition 1 */
+#define BPMP_C2C_STATUS_C2C1_PLLCAL_FAIL 13
+/** @brief clock detection times out - partition 0 */
+#define BPMP_C2C_STATUS_C2C0_CLKDET_FAIL 14
+/** @brief clock detection times out - partition 1 */
+#define BPMP_C2C_STATUS_C2C1_CLKDET_FAIL 15
+/** @brief Final trainings fail partition 0 */
+#define BPMP_C2C_STATUS_C2C0_TR_FAIL 16
+/** @brief Final trainings fail partition 1 */
+#define BPMP_C2C_STATUS_C2C1_TR_FAIL 17
+/** @brief C2C FW init done */
+#define NV_GFW_GLOBAL_DEVINIT_C2C_STATUS_C2C_FW_INIT_DONE 20
+/** @brief C2C FW init failed partition 0 */
+#define NV_GFW_GLOBAL_DEVINIT_C2C_STATUS_C2C0_FW_INIT_FAIL 21
+/** @brief C2C FW init failed partition 1 */
+#define NV_GFW_GLOBAL_DEVINIT_C2C_STATUS_C2C1_FW_INIT_FAIL 22
+/** @brief no failure seen, c2c init was successful */
+#define BPMP_C2C_STATUS_C2C_LINK_TRAIN_PASS 255
+/** @} bpmp_c2c_status */
+
+/**
+ * @ingroup MRQ_Codes
+ * @def MRQ_C2C
+ * @brief Control C2C partitions initialization.
+ *
+ * * Initiators: Any
+ * * Targets: BPMP
+ * * Request Payload: @ref mrq_c2c_request
+ * * Response Payload: @ref mrq_c2c_response
+ *
+ * @addtogroup C2C
+ * @{
+ */
+enum mrq_c2c_cmd {
+ /**
+ * @brief Check whether the BPMP driver supports the specified request
+ * type
+ *
+ * mrq_response:: err is 0 if the specified request is supported and
+ * -#BPMP_ENODEV otherwise
+ */
+ CMD_C2C_QUERY_ABI = 0,
+
+ /**
+ * @brief Start C2C initialization
+ *
+ * mrq_response:err is
+ * * 0: Success
+ * * -#BPMP_ENODEV: MRQ_C2C is not supported by BPMP-FW
+ * * -#BPMP_ENAVAIL: Invalid request parameters
+ * * -#BPMP_EACCES: Request is not accepted
+ */
+ CMD_C2C_START_INITIALIZATION = 1,
+
+ /**
+ * @brief Command to query current C2C training status
+ *
+ * This command will return the result of the latest C2C re-training that is initiated with
+ * MRQ_C2C.CMD_C2C_START_INITIALIZATION or MRQ_C2C.CMD_C2C_START_HOTRESET calls.
+ * If no training has been initiated yet, the command will return code BPMP_C2C_STATUS_INIT_NOT_STARTED.
+ *
+ * mrq_response:err is
+ * * 0: Success
+ * * -#BPMP_ENODEV: MRQ_C2C is not supported by BPMP-FW
+ * * -#BPMP_EACCES: Request is not accepted
+ */
+ CMD_C2C_GET_STATUS = 2,
+ /**
+ * @brief C2C hot-reset precondition
+ *
+ * mrq_response:err is
+ * * 0: Success
+ * * -#BPMP_ENODEV: MRQ_C2C is not supported by BPMP-FW
+ * * -#BPMP_ENAVAIL: Invalid request parameters
+ * * -#BPMP_EACCES: Request is not accepted
+ */
+ CMD_C2C_HOTRESET_PREP = 3,
+ /**
+ * @brief Start C2C hot-reset
+ *
+ * mrq_response:err is
+ * * 0: Success
+ * * -#BPMP_ENODEV: MRQ_C2C is not supported by BPMP-FW
+ * * -#BPMP_ENAVAIL: Invalid request parameters
+ * * -#BPMP_EACCES: Request is not accepted
+ */
+ CMD_C2C_START_HOTRESET = 4,
+
+ CMD_C2C_MAX
+};
+
+/**
+ * @brief Request data for #MRQ_C2C command CMD_C2C_QUERY_ABI
+ */
+struct cmd_c2c_query_abi_request {
+ /** @brief Command identifier to be queried */
+ uint32_t cmd;
+} BPMP_ABI_PACKED;
+
+/**
+ * @brief Request data for #MRQ_C2C command CMD_C2C_START_INITIALIZATION
+ */
+struct cmd_c2c_start_init_request {
+ /** @brief 1: partition 0; 2: partition 1; 3: partition 0 and 1; */
+ uint8_t partitions;
+} BPMP_ABI_PACKED;
+
+/**
+ * @brief Response data for #MRQ_C2C command CMD_C2C_START_INITIALIZATION
+ */
+struct cmd_c2c_start_init_response {
+ /** @brief Refer to @ref bpmp_c2c_status */
+ uint8_t status;
+} BPMP_ABI_PACKED;
+
+/**
+ * @brief Response data for #MRQ_C2C command CMD_C2C_GET_STATUS
+ */
+struct cmd_c2c_get_status_response {
+ /** @brief Refer to @ref bpmp_c2c_status */
+ uint8_t status;
+} BPMP_ABI_PACKED;
+
+/**
+ * @brief Request data for #MRQ_C2C command CMD_C2C_HOTRESET_PREP
+ */
+struct cmd_c2c_hotreset_prep_request {
+ /** @brief 1: partition 0; 2: partition 1; 3: partition 0 and 1; */
+ uint8_t partitions;
+} BPMP_ABI_PACKED;
+
+/**
+ * @brief Request data for #MRQ_C2C command CMD_C2C_START_HOTRESET
+ */
+struct cmd_c2c_start_hotreset_request {
+ /** @brief 1: partition 0; 2: partition 1; 3: partition 0 and 1; */
+ uint8_t partitions;
+} BPMP_ABI_PACKED;
+
+/**
+ * @brief Response data for #MRQ_C2C command CMD_C2C_START_HOTRESET
+ */
+struct cmd_c2c_start_hotreset_response {
+ /** @brief Refer to @ref bpmp_c2c_status */
+ uint8_t status;
+} BPMP_ABI_PACKED;
+
+/**
+ * @brief Request with #MRQ_C2C
+ *
+ * |sub-command |payload |
+ * |-----------------------------|-------------------------------|
+ * |CMD_C2C_QUERY_ABI |cmd_c2c_query_abi_request |
+ * |CMD_C2C_START_INITIALIZATION |cmd_c2c_start_init_request |
+ * |CMD_C2C_GET_STATUS | |
+ * |CMD_C2C_HOTRESET_PREP |cmd_c2c_hotreset_prep_request |
+ * |CMD_C2C_START_HOTRESET |cmd_c2c_start_hotreset_request |
+
+ */
+struct mrq_c2c_request {
+ uint32_t cmd;
+ union {
+ struct cmd_c2c_query_abi_request c2c_query_abi_req;
+ struct cmd_c2c_start_init_request c2c_start_init_req;
+ struct cmd_c2c_hotreset_prep_request c2c_hotreset_prep_req;
+ struct cmd_c2c_start_hotreset_request c2c_start_hotreset_req;
+ } BPMP_UNION_ANON;
+} BPMP_ABI_PACKED;
+
+/**
+ * @brief Response to MRQ_C2C
+ *
+ * |sub-command |payload |
+ * |-----------------------------|--------------------------------|
+ * |CMD_C2C_QUERY_ABI | |
+ * |CMD_C2C_START_INITIALIZATION |cmd_c2c_start_init_response |
+ * |CMD_C2C_GET_STATUS |cmd_c2c_get_status_response |
+ * |CMD_C2C_HOTRESET_PREP | |
+ * |CMD_C2C_START_HOTRESET |cmd_c2c_start_hotreset_response |
+ */
+struct mrq_c2c_response {
+ union {
+ struct cmd_c2c_start_init_response c2c_start_init_resp;
+ struct cmd_c2c_get_status_response c2c_get_status_resp;
+ struct cmd_c2c_start_hotreset_response c2c_start_hotreset_resp;
+ } BPMP_UNION_ANON;
+} BPMP_ABI_PACKED;
+/** @} */
+/** @endcond */
+
+
+/** @cond (bpmp_t264)
+ * @ingroup MRQ_Codes
+ * @def MRQ_PCIE
+ * @brief Perform a PCIE operation
+ *
+ * * Initiators: CCPLEX
+ * * Targets: BPMP
+ * * Request Payload: @ref mrq_pcie_request
+ *
+ * @addtogroup PCIE
+ * @{
+ */
+
+/**
+ * @brief Sub-command identifiers for #MRQ_PCIE.
+ */
+enum mrq_pcie_cmd {
+ /** @brief Initialize PCIE EP controller. */
+ CMD_PCIE_EP_CONTROLLER_INIT = 0,
+ /** @brief Disable PCIE EP controller. */
+ CMD_PCIE_EP_CONTROLLER_OFF = 1,
+
+ /** @brief Disable PCIE RP controller. */
+ CMD_PCIE_RP_CONTROLLER_OFF = 100,
+
+ CMD_PCIE_MAX,
+};
+
+/**
+ * @brief Request payload for #MRQ_PCIE sub-command #CMD_PCIE_EP_CONTROLLER_INIT.
+ */
+struct cmd_pcie_ep_controller_init_request {
+ /**
+ * @brief PCIe EP controller number.
+ * Valid entries for T264 are 2, 4 and 5.
+ */
+ uint8_t ep_controller;
+ /**
+ * @brief PCIe EP function programming interface code.
+ * Valid range in HW is [0, 0xFFU], BPMP-FW programs the input value without any check.
+ * It is up to the requester to send valid input as documented in "PCI CODE AND ID
+ * ASSIGNMENT SPECIFICATION".
+ */
+ uint8_t progif_code;
+ /**
+ * @brief PCIe EP function sub-class code.
+ * Valid range in HW is [0, 0xFFU], BPMP-FW programs the input value without any check.
+ * It is up to the requester to send valid input as documented in "PCI CODE AND ID
+ * ASSIGNMENT SPECIFICATION".
+ */
+ uint8_t subclass_code;
+ /**
+ * @brief PCIe EP function base class code.
+ * Valid range in HW is [0, 0xFFU], BPMP-FW programs the input value without any check.
+ * It is up to the requester to send valid input as documented in "PCI CODE AND ID
+ * ASSIGNMENT SPECIFICATION".
+ */
+ uint8_t baseclass_code;
+ /**
+ * @brief PCIe EP function device id.
+ * Valid range is [0, 0x7FU], only LSB 7 bits are writable in 16-bit PCI device id.
+ * Valid range check is done on input value and returns -BPMP_EINVAL on failure.
+ */
+ uint8_t deviceid;
+ /**
+ * @brief PCIe EP EP BAR1 size.
+ * Valid range is [6U, 16U], which translate to [64MB, 64GB] size.
+ * Valid range check is done on input value and returns -BPMP_EINVAL on failure.
+ */
+ uint8_t bar1_size;
+} BPMP_ABI_PACKED;
+
+/**
+ * @brief Request payload for #MRQ_PCIE sub-command #CMD_PCIE_EP_CONTROLLER_OFF.
+ */
+struct cmd_pcie_ep_controller_off_request {
+ /** @brief EP controller number, T264 valid: 2, 4, 5. */
+ uint8_t ep_controller;
+} BPMP_ABI_PACKED;
+
+/**
+ * @brief Request payload for #MRQ_PCIE sub-command #CMD_PCIE_RP_CONTROLLER_OFF.
+ */
+struct cmd_pcie_rp_controller_off_request {
+ /** @brief RP controller number, T264 valid: 1-5 */
+ uint8_t rp_controller;
+} BPMP_ABI_PACKED;
+
+/**
+ * @ingroup PCIE
+ * @brief Request payload for the #MRQ_PCIE command.
+ *
+ * Used by the sender of an #MRQ_PCIE message to control PCIE.
+ * Below table shows sub-commands with their corresponding payload data.
+ *
+ * |sub-command |payload |
+ * |--------------------------------------|-----------------------------------------|
+ * |#CMD_PCIE_EP_CONTROLLER_INIT |#cmd_pcie_ep_controller_init_request |
+ * |#CMD_PCIE_EP_CONTROLLER_OFF |#cmd_pcie_ep_controller_off_request |
+ *
+ * @cond (!bpmp_safe)
+ *
+ * The following additional MRQs are supported on non-functional-safety
+ * builds:
+ * |sub-command |payload |
+ * |--------------------------------------|-----------------------------------------|
+ * |#CMD_PCIE_RP_CONTROLLER_OFF |#cmd_pcie_rp_controller_off_request |
+ *
+ * @endcond
+ *
+ */
+struct mrq_pcie_request {
+ /** @brief Sub-command ID from @ref mrq_pcie_cmd. */
+ uint32_t cmd;
+
+ union {
+ struct cmd_pcie_ep_controller_init_request ep_ctrlr_init;
+ struct cmd_pcie_ep_controller_off_request ep_ctrlr_off;
+ /** @cond (!bpmp_safe) */
+ struct cmd_pcie_rp_controller_off_request rp_ctrlr_off;
+ /** @endcond */
+ } BPMP_UNION_ANON;
+} BPMP_ABI_PACKED;
+
+/** @} PCIE */
+/** @endcond */
+
+/** @cond (bpmp_t264)
+ * @ingroup MRQ_Codes
+ * @def MRQ_CR7
+ * @brief Perform a CR7 operation
+ *
+ * * Initiators: CPU_S
+ * * Targets: BPMP
+ * * Request Payload: @ref mrq_cr7_request
+ *
+ * @addtogroup CR7
+ * @{
+ */
+
+/**
+ * @brief Payload for #MRQ_CR7
+ * 2 fields for future parameters are provided. These must be 0 currently.
+ */
+struct cmd_cr7_request {
+ uint32_t fld0;
+ uint32_t fld1;
+} BPMP_ABI_PACKED;
+
+struct cmd_cr7_query_abi_request {
+ /** #MRQ_CR7 sub-command identifier from @ref mrq_cr7_cmd */
+ uint32_t type;
+} BPMP_ABI_PACKED;
+
+/**
+ * @brief Sub-command identifiers for #MRQ_CR7.
+ */
+enum mrq_cr7_cmd {
+ /**
+ * @brief Check whether the BPMP driver supports the specified request
+ * type
+ *
+ * mrq_response:: err is 0 if the specified request is supported and
+ * -#BPMP_ENODEV otherwise
+ */
+ CMD_CR7_QUERY_ABI = 0,
+
+ /** @brief Enter CR7 state on the package BPMP-FW is running on. */
+ CMD_CR7_ENTRY = 1,
+ /** @brief Exit CR7 state on the package BPMP-FW is running on. */
+ CMD_CR7_EXIT = 2,
+
+ CMD_CR7_MAX,
+};
+
+/**
+ * @ingroup CR7
+ * @brief #MRQ_CR7 structure
+ *
+ * |Sub-command |Payload |
+ * |----------------------------|---------------------------|
+ * |#CMD_CR7_QUERY_ABI | #cmd_cr7_query_abi_request|
+ * |#CMD_CR7_ENTRY | #cmd_cr7_request |
+ * |#CMD_CR7_EXIT | #cmd_cr7_request |
+
+ */
+struct mrq_cr7_request {
+ /** @brief Sub-command ID from @ref mrq_cr7_cmd. */
+ uint32_t cmd;
+ union {
+ struct cmd_cr7_query_abi_request query_abi;
+ struct cmd_cr7_request cr7_request;
+ } BPMP_UNION_ANON;
+} BPMP_ABI_PACKED;
+
+/** @} CR7 */
+/** @endcond */
+
+/** @cond (bpmp_tb500)
+ * @ingroup MRQ_Codes
+ * @def MRQ_HWPM
+ * @brief Configure and query HWPM functionality
+ *
+ * * Initiators: CCPLEX
+ * * Targets: BPMP
+ * * Request Payload: @ref mrq_hwpm_request
+ * * Response Payload: @ref mrq_hwpm_response
+ *
+ * @addtogroup HWPM
+ * @{
+ */
+
+/**
+ * @brief Sub-command identifiers for #MRQ_HWPM.
+ */
+enum mrq_hwpm_cmd {
+ /**
+ * @brief Check whether the BPMP-FW supports the specified
+ * #MRQ_HWPM sub-command.
+ *
+ * mrq_response:err is 0 if the specified request is
+ * supported and -#BPMP_ENODEV otherwise.
+ */
+ CMD_HWPM_QUERY_ABI = 1,
+
+ /**
+ * @brief Configure IPMU triggers
+ *
+ * mrq_response:err is defined as:
+ *
+ * | Value | Description |
+ * | -------------- | ------------------------------------------- |
+ * | 0 | Success |
+ * | -#BPMP_ENODEV | #MRQ_HWPM is not supported by BPMP-FW. |
+ * | -#BPMP_ENOTSUP | Subcommand is not supported by BPMP-FW. |
+ * | -#BPMP_EINVAL | Invalid request parameters. |
+ */
+ CMD_HWPM_IPMU_SET_TRIGGERS = 2,
+
+ /**
+ * @brief Configure IPMU payloads and shifts
+ *
+ * mrq_response:err is defined as:
+ *
+ * | Value | Description |
+ * | -------------- | ------------------------------------------- |
+ * | 0 | Success |
+ * | -#BPMP_ENODEV | #MRQ_HWPM is not supported by BPMP-FW. |
+ * | -#BPMP_ENOTSUP | Subcommand is not supported by BPMP-FW. |
+ * | -#BPMP_EINVAL | Invalid request parameters. |
+ */
+ CMD_HWPM_IPMU_SET_PAYLOADS_SHIFTS = 3,
+
+ /**
+ * @brief Get maximum number of payloads
+ *
+ * mrq_response:err is defined as:
+ *
+ * | Value | Description |
+ * | -------------- | ------------------------------------------- |
+ * | 0 | Success |
+ * | -#BPMP_ENODEV | #MRQ_HWPM is not supported by BPMP-FW. |
+ * | -#BPMP_ENOTSUP | Subcommand is not supported by BPMP-FW. |
+ */
+ CMD_HWPM_IPMU_GET_MAX_PAYLOADS = 4,
+
+ /**
+ * @brief Configure NVTHERM sample rate
+ *
+ * mrq_response:err is defined as:
+ *
+ * | Value | Description |
+ * | -------------- | ------------------------------------------- |
+ * | 0 | Success |
+ * | -#BPMP_ENODEV | #MRQ_HWPM is not supported by BPMP-FW. |
+ * | -#BPMP_ENOTSUP | Subcommand is not supported by BPMP-FW. |
+ * | -#BPMP_EINVAL | Invalid request parameters. |
+ */
+ CMD_HWPM_NVTHERM_SET_SAMPLE_RATE = 5,
+
+ /**
+ * @brief Set NVTHERM bubble interval
+ *
+ * mrq_response:err is defined as:
+ *
+ * | Value | Description |
+ * | -------------- | ------------------------------------------- |
+ * | 0 | Success |
+ * | -#BPMP_ENODEV | #MRQ_HWPM is not supported by BPMP-FW. |
+ * | -#BPMP_ENOTSUP | Subcommand is not supported by BPMP-FW. |
+ * | -#BPMP_EINVAL | Invalid request parameters. |
+ */
+ CMD_HWPM_NVTHERM_SET_BUBBLE_INTERVAL = 6,
+
+ /**
+ * @brief Configure NVTHERM DG flexible channels
+ *
+ * mrq_response:err is defined as:
+ *
+ * | Value | Description |
+ * | -------------- | ------------------------------------------- |
+ * | 0 | Success |
+ * | -#BPMP_ENODEV | #MRQ_HWPM is not supported by BPMP-FW. |
+ * | -#BPMP_ENOTSUP | Subcommand is not supported by BPMP-FW. |
+ * | -#BPMP_EINVAL | Invalid request parameters. |
+ */
+ CMD_HWPM_NVTHERM_SET_FLEX_CHANNELS = 7,
+
+ /**
+ * @brief Get ISENSE sensor name
+ *
+ * mrq_response:err is defined as:
+ *
+ * | Value | Description |
+ * | -------------- | ------------------------------------------- |
+ * | 0 | Success |
+ * | -#BPMP_ENODEV | #MRQ_HWPM is not supported by BPMP-FW. |
+ * | -#BPMP_ENOTSUP | Subcommand is not supported by BPMP-FW. |
+ * | -#BPMP_EINVAL | Invalid request parameters. |
+ */
+ CMD_HWPM_ISENSE_GET_SENSOR_NAME = 8,
+
+ /**
+ * @brief Get ISENSE sensor channel
+ *
+ * mrq_response:err is defined as:
+ *
+ * | Value | Description |
+ * | -------------- | ------------------------------------------- |
+ * | 0 | Success |
+ * | -#BPMP_ENODEV | #MRQ_HWPM is not supported by BPMP-FW. |
+ * | -#BPMP_ENOTSUP | Subcommand is not supported by BPMP-FW. |
+ * | -#BPMP_EINVAL | Invalid request parameters. |
+ */
+ CMD_HWPM_ISENSE_GET_SENSOR_CHANNEL = 9,
+
+ /**
+ * @brief Get ISENSE sensor scale factor
+ *
+ * mrq_response:err is defined as:
+ *
+ * | Value | Description |
+ * | -------------- | ------------------------------------------- |
+ * | 0 | Success |
+ * | -#BPMP_ENODEV | #MRQ_HWPM is not supported by BPMP-FW. |
+ * | -#BPMP_ENOTSUP | Subcommand is not supported by BPMP-FW. |
+ * | -#BPMP_EINVAL | Invalid request parameters. |
+ */
+ CMD_HWPM_ISENSE_GET_SENSOR_SCALE_FACTOR = 10,
+
+ /**
+ * @brief Get ISENSE sensor offset
+ *
+ * mrq_response:err is defined as:
+ *
+ * | Value | Description |
+ * | -------------- | ------------------------------------------- |
+ * | 0 | Success |
+ * | -#BPMP_ENODEV | #MRQ_HWPM is not supported by BPMP-FW. |
+ * | -#BPMP_ENOTSUP | Subcommand is not supported by BPMP-FW. |
+ * | -#BPMP_EINVAL | Invalid request parameters. |
+ * | -#BPMP_ENODATA | No sensor offset. |
+ */
+ CMD_HWPM_ISENSE_GET_SENSOR_OFFSET = 11,
+
+ /**
+ * @brief Get ISENSE sum block name
+ *
+ * mrq_response:err is defined as:
+ *
+ * | Value | Description |
+ * | -------------- | ------------------------------------------- |
+ * | 0 | Success |
+ * | -#BPMP_ENODEV | #MRQ_HWPM is not supported by BPMP-FW. |
+ * | -#BPMP_ENOTSUP | Subcommand is not supported by BPMP-FW. |
+ * | -#BPMP_EINVAL | Invalid request parameters. |
+ */
+ CMD_HWPM_ISENSE_GET_SUM_BLOCK_NAME = 12,
+
+ /**
+ * @brief Get ISENSE sum input sensor IDs
+ *
+ * mrq_response:err is defined as:
+ *
+ * | Value | Description |
+ * | -------------- | ------------------------------------------- |
+ * | 0 | Success |
+ * | -#BPMP_ENODEV | #MRQ_HWPM is not supported by BPMP-FW. |
+ * | -#BPMP_ENOTSUP | Subcommand is not supported by BPMP-FW. |
+ * | -#BPMP_EINVAL | Invalid request parameters. |
+ */
+ CMD_HWPM_ISENSE_GET_SUM_BLOCK_INPUTS = 13,
+
+ /**
+ * @brief Largest supported #MRQ_HWPM sub-command identifier + 1
+ */
+ CMD_HWPM_MAX,
+};
+
+/**
+ * @brief Request data for #MRQ_HWPM sub-command #CMD_HWPM_QUERY_ABI
+ */
+struct cmd_hwpm_query_abi_req {
+ /** @brief Sub-command identifier from @ref mrq_hwpm_cmd */
+ uint32_t cmd_code;
+} BPMP_ABI_PACKED;
+
+/**
+ * @brief Maximum array length for IPMU trigger bitmask
+ */
+#define HWPM_IPMU_TRIGGER_ARR_LEN 28U
+
+/**
+ * @brief Request data for #MRQ_HWPM sub-command #CMD_HWPM_IPMU_SET_TRIGGERS
+ */
+struct cmd_hwpm_ipmu_set_triggers_req {
+ /** @brief IPMU physical ID
+ *
+ * @note Valid range from [0, MAX_CPU_CORES), see @ref bpmp_hwpm_core_config
+ */
+ uint32_t ipmu_phys_id;
+ /** @brief Trigger bitmask, see @ref bpmp_ipmu_trigger_ids
+ *
+ * @note Setting a trigger bit will cause the associated trigger to
+ * generate an output packet from IPMU to the HWPM perfmux.
+ * @note Up to a maximum possible 896 triggers
+ */
+ uint32_t triggers[HWPM_IPMU_TRIGGER_ARR_LEN];
+} BPMP_ABI_PACKED;
+
+/**
+ * @brief Array length for IPMU payload bitmask
+ */
+#define HWPM_IPMU_PAYLOAD_ARR_LEN 26U
+
+/**
+ * @brief Array length for IPMU payload shift bitmask
+ */
+#define HWPM_IPMU_SHIFT_ARR_LEN 2U
+
+/**
+ * @brief Request data for #MRQ_HWPM sub-command #CMD_HWPM_IPMU_SET_PAYLOADS_SHIFTS
+ */
+struct cmd_hwpm_ipmu_set_payloads_shifts_req {
+ /** @brief IPMU physical ID
+ *
+ * @note Valid range from [0, MAX_CPU_CORES), see @ref bpmp_hwpm_core_config
+ */
+ uint32_t ipmu_phys_id;
+ /** @brief Payload bitmask, see @ref bpmp_ipmu_payload_ids
+ *
+ * @note Setting a payload bit will add the associated payload to the
+ * IPMU output packet.
+ * @note The maximum number of payloads is platform dependent,
+ * @see #CMD_HWPM_IPMU_GET_MAX_PAYLOADS
+ * @note To disable IPMU streaming on this instance, set all payload bits to 0.
+ * @note Up to a maximum of 832 available payloads
+ */
+ uint32_t payloads[HWPM_IPMU_PAYLOAD_ARR_LEN];
+ /**
+ * @brief Payload shift mask
+ *
+ * @note Setting the i-th shift bit will right-shift the
+ * i-th enabled payload by 1 bit.
+ * @note Up to a maximum of 64 simultaneous emitted payloads
+ */
+ uint32_t shifts[HWPM_IPMU_SHIFT_ARR_LEN];
+} BPMP_ABI_PACKED;
+
+/**
+ * @brief Request data for #MRQ_HWPM sub-command #CMD_HWPM_IPMU_GET_MAX_PAYLOADS
+ */
+struct cmd_hwpm_ipmu_get_max_payloads_req {
+ BPMP_ABI_EMPTY
+} BPMP_ABI_PACKED;
+
+/**
+ * @brief Request data for #MRQ_HWPM sub-command #CMD_HWPM_NVTHERM_SET_SAMPLE_RATE
+ */
+struct cmd_hwpm_nvtherm_set_sample_rate_req {
+ /** @brief Sample rate in microseconds
+ *
+ * @note Requesting a sample rate of 0 will disable NVTHERM streaming.
+ */
+ uint32_t sample_rate;
+} BPMP_ABI_PACKED;
+
+/**
+ * @brief Request data for #MRQ_HWPM sub-command #CMD_HWPM_NVTHERM_SET_BUBBLE_INTERVAL
+ */
+struct cmd_hwpm_nvtherm_set_bubble_interval_req {
+ /** @brief Bubble interval in microseconds */
+ uint32_t bubble_interval;
+} BPMP_ABI_PACKED;
+
+/**
+ * @brief Maximum array length for NVTHERM flexible channel bitmask
+ */
+#define HWPM_NVTHERM_FLEX_CHANNEL_ARR_LEN 29U
+
+/**
+ * @brief Request data for #MRQ_HWPM sub-command #CMD_HWPM_NVTHERM_SET_FLEX_CHANNELS
+ */
+struct cmd_hwpm_nvtherm_set_flex_channels_req {
+ /** @brief NVTHERM flexible channel bitmask
+ *
+ * @see #bpmp_nvtherm_flex_channel_ids
+ *
+ * @note Up to a maximum of 928 flexible channels
+ */
+ uint32_t channels[HWPM_NVTHERM_FLEX_CHANNEL_ARR_LEN];
+} BPMP_ABI_PACKED;
+
+/**
+ * @brief Request data for #MRQ_HWPM sub-command #CMD_HWPM_ISENSE_GET_SENSOR_NAME
+ */
+struct cmd_hwpm_isense_get_sensor_name_req {
+ /** @brief Sensor ID from @ref bpmp_isense_sensor_ids */
+ uint32_t sensor_id;
+} BPMP_ABI_PACKED;
+
+/**
+ * @brief Request data for #MRQ_HWPM sub-command #CMD_HWPM_ISENSE_GET_SENSOR_CHANNEL
+ */
+struct cmd_hwpm_isense_get_sensor_channel_req {
+ /** @brief Sensor ID from @ref bpmp_isense_sensor_ids */
+ uint32_t sensor_id;
+} BPMP_ABI_PACKED;
+
+/**
+ * @brief Request data for #MRQ_HWPM sub-command #CMD_HWPM_ISENSE_GET_SENSOR_SCALE_FACTOR
+ */
+struct cmd_hwpm_isense_get_sensor_scale_factor_req {
+ /** @brief Sensor ID from @ref bpmp_isense_sensor_ids */
+ uint32_t sensor_id;
+} BPMP_ABI_PACKED;
+
+/**
+ * @brief Request data for #MRQ_HWPM sub-command #CMD_HWPM_ISENSE_GET_SENSOR_OFFSET
+ */
+struct cmd_hwpm_isense_get_sensor_offset_req {
+ /** @brief Sensor ID from @ref bpmp_isense_sensor_ids */
+ uint32_t sensor_id;
+} BPMP_ABI_PACKED;
+
+/**
+ * @brief Request data for #MRQ_HWPM sub-command #CMD_HWPM_ISENSE_GET_SUM_BLOCK_NAME
+ */
+struct cmd_hwpm_isense_get_sum_block_name_req {
+ /** @brief Sum block index */
+ uint32_t sum_block_index;
+} BPMP_ABI_PACKED;
+
+/**
+ * @brief Request data for #MRQ_HWPM sub-command #CMD_HWPM_ISENSE_GET_SUM_BLOCK_INPUTS
+ */
+struct cmd_hwpm_isense_get_sum_block_inputs_req {
+ /** @brief Sum block index */
+ uint32_t sum_block_index;
+} BPMP_ABI_PACKED;
+
+/**
+ * @brief Response data for #MRQ_HWPM sub-command #CMD_HWPM_IPMU_GET_MAX_PAYLOADS
+ */
+struct cmd_hwpm_ipmu_get_max_payloads_resp {
+ /** @brief Maximum number of payloads */
+ uint32_t max_payloads;
+} BPMP_ABI_PACKED;
+
+/**
+ * @brief Maximum array length for ISENSE sensor name
+ */
+#define HWPM_ISENSE_SENSOR_MAX_NAME_LEN 64U
+
+/**
+ * @brief Response data for #MRQ_HWPM sub-command #CMD_HWPM_ISENSE_GET_SENSOR_NAME
+ */
+struct cmd_hwpm_isense_get_sensor_name_resp {
+ /** @brief Sensor name */
+ char sensor_name[HWPM_ISENSE_SENSOR_MAX_NAME_LEN];
+} BPMP_ABI_PACKED;
+
+/**
+ * @brief Response data for #MRQ_HWPM sub-command #CMD_HWPM_ISENSE_GET_SENSOR_CHANNEL
+ */
+struct cmd_hwpm_isense_get_sensor_channel_resp {
+ /** @brief Physical channel index */
+ uint32_t channel_index;
+} BPMP_ABI_PACKED;
+
+/**
+ * @brief Response data for #MRQ_HWPM sub-command #CMD_HWPM_ISENSE_GET_SENSOR_SCALE_FACTOR
+ */
+struct cmd_hwpm_isense_get_sensor_scale_factor_resp {
+ /** @brief Scale factor */
+ float scale_factor;
+} BPMP_ABI_PACKED;
+
+/**
+ * @brief Response data for #MRQ_HWPM sub-command #CMD_HWPM_ISENSE_GET_SENSOR_OFFSET
+ */
+struct cmd_hwpm_isense_get_sensor_offset_resp {
+ /** @brief Offset sensor ID */
+ uint32_t offset_sensor_id;
+} BPMP_ABI_PACKED;
+
+/**
+ * @brief Maximum array length for ISENSE sum name
+ */
+#define HWPM_ISENSE_SUM_BLOCK_MAX_NAME_LEN 64U
+
+/**
+ * @brief Response data for #MRQ_HWPM sub-command #CMD_HWPM_ISENSE_GET_SUM_BLOCK_NAME
+ */
+struct cmd_hwpm_isense_get_sum_block_name_resp {
+ /** @brief Sum block name */
+ char sum_block_name[HWPM_ISENSE_SUM_BLOCK_MAX_NAME_LEN];
+} BPMP_ABI_PACKED;
+
+/**
+ * @brief Maximum array length for ISENSE sum block input sensor IDs
+ */
+#define HWPM_ISENSE_SUM_BLOCK_INPUTS_MAX 16U
+
+/**
+ * @brief Response data for #MRQ_HWPM sub-command #CMD_HWPM_ISENSE_GET_SUM_BLOCK_INPUTS
+ */
+struct cmd_hwpm_isense_get_sum_block_inputs_resp {
+ /** @brief Input channel indices; negative if no input is applied */
+ int32_t input_channel_idx[HWPM_ISENSE_SUM_BLOCK_INPUTS_MAX];
+} BPMP_ABI_PACKED;
+
+/**
+ * @brief Request payload for the #MRQ_HWPM -command
+ *
+ * | Sub-command | Request payload |
+ * | ---------------------------------------- | -------------------------------------------- |
+ * | #CMD_HWPM_QUERY_ABI | #cmd_hwpm_query_abi_req |
+ * | #CMD_HWPM_IPMU_SET_TRIGGERS | #cmd_hwpm_ipmu_set_triggers_req |
+ * | #CMD_HWPM_IPMU_SET_PAYLOADS_SHIFTS | #cmd_hwpm_ipmu_set_payloads_shifts_req |
+ * | #CMD_HWPM_IPMU_GET_MAX_PAYLOADS | #cmd_hwpm_ipmu_get_max_payloads_req |
+ * | #CMD_HWPM_NVTHERM_SET_SAMPLE_RATE | #cmd_hwpm_nvtherm_set_sample_rate_req |
+ * | #CMD_HWPM_NVTHERM_SET_BUBBLE_INTERVAL | #cmd_hwpm_nvtherm_set_bubble_interval_req |
+ * | #CMD_HWPM_NVTHERM_SET_FLEX_CHANNELS | #cmd_hwpm_nvtherm_set_flex_channels_req |
+ * | #CMD_HWPM_ISENSE_GET_SENSOR_CHANNEL | #cmd_hwpm_isense_get_sensor_channel_req |
+ * | #CMD_HWPM_ISENSE_GET_SENSOR_SCALE_FACTOR | #cmd_hwpm_isense_get_sensor_scale_factor_req |
+ * | #CMD_HWPM_ISENSE_GET_SENSOR_OFFSET | #cmd_hwpm_isense_get_sensor_offset_req |
+ * | #CMD_HWPM_ISENSE_GET_SUM_BLOCK_NAME | #cmd_hwpm_isense_get_sum_block_name_req |
+ * | #CMD_HWPM_ISENSE_GET_SUM_BLOCK_INPUTS | #cmd_hwpm_isense_get_sum_block_inputs_req |
+ */
+struct mrq_hwpm_request {
+ uint32_t cmd;
+ union {
+ struct cmd_hwpm_query_abi_req query_abi;
+ struct cmd_hwpm_ipmu_set_triggers_req ipmu_set_triggers;
+ struct cmd_hwpm_ipmu_set_payloads_shifts_req ipmu_set_payloads_shifts;
+ struct cmd_hwpm_ipmu_get_max_payloads_req ipmu_get_max_payloads;
+ struct cmd_hwpm_nvtherm_set_sample_rate_req nvtherm_set_sample_rate;
+ struct cmd_hwpm_nvtherm_set_bubble_interval_req nvtherm_set_bubble_interval;
+ struct cmd_hwpm_nvtherm_set_flex_channels_req nvtherm_set_flex_channels;
+ struct cmd_hwpm_isense_get_sensor_name_req isense_get_sensor_name;
+ struct cmd_hwpm_isense_get_sensor_channel_req isense_get_sensor_channel;
+ struct cmd_hwpm_isense_get_sensor_scale_factor_req isense_get_sensor_scale_factor;
+ struct cmd_hwpm_isense_get_sensor_offset_req isense_get_sensor_offset;
+ struct cmd_hwpm_isense_get_sum_block_name_req isense_get_sum_block_name;
+ struct cmd_hwpm_isense_get_sum_block_inputs_req isense_get_sum_block_inputs;
+ } BPMP_UNION_ANON;
+} BPMP_ABI_PACKED;
+
+/**
+ * @brief Response payload for the #MRQ_HWPM -command
+ *
+ * | Sub-command | Response payload |
+ * | ---------------------------------------- | --------------------------------------------- |
+ * | #CMD_HWPM_QUERY_ABI | - |
+ * | #CMD_HWPM_IPMU_SET_TRIGGERS | - |
+ * | #CMD_HWPM_IPMU_SET_PAYLOADS_SHIFTS | - |
+ * | #CMD_HWPM_IPMU_GET_MAX_PAYLOADS | #cmd_hwpm_ipmu_get_max_payloads_resp |
+ * | #CMD_HWPM_NVTHERM_SET_SAMPLE_RATE | - |
+ * | #CMD_HWPM_NVTHERM_SET_BUBBLE_INTERVAL | - |
+ * | #CMD_HWPM_NVTHERM_SET_FLEX_CHANNELS | - |
+ * | #CMD_HWPM_ISENSE_GET_SENSOR_NAME | #cmd_hwpm_isense_get_sensor_name_resp |
+ * | #CMD_HWPM_ISENSE_GET_SENSOR_CHANNEL | #cmd_hwpm_isense_get_sensor_channel_resp |
+ * | #CMD_HWPM_ISENSE_GET_SENSOR_SCALE_FACTOR | #cmd_hwpm_isense_get_sensor_scale_factor_resp |
+ * | #CMD_HWPM_ISENSE_GET_SENSOR_OFFSET | #cmd_hwpm_isense_get_sensor_offset_resp |
+ * | #CMD_HWPM_ISENSE_GET_SUM_BLOCK_NAME | #cmd_hwpm_isense_get_sum_block_name_resp |
+ * | #CMD_HWPM_ISENSE_GET_SUM_BLOCK_INPUTS | #cmd_hwpm_isense_get_sum_block_inputs_resp |
+ */
+struct mrq_hwpm_response {
+ uint32_t err;
+ union {
+ struct cmd_hwpm_ipmu_get_max_payloads_resp ipmu_get_max_payloads;
+ struct cmd_hwpm_isense_get_sensor_name_resp isense_get_sensor_name;
+ struct cmd_hwpm_isense_get_sensor_channel_resp isense_get_sensor_channel;
+ struct cmd_hwpm_isense_get_sensor_scale_factor_resp isense_get_sensor_scale_factor;
+ struct cmd_hwpm_isense_get_sensor_offset_resp isense_get_sensor_offset;
+ struct cmd_hwpm_isense_get_sum_block_name_resp isense_get_sum_block_name;
+ struct cmd_hwpm_isense_get_sum_block_inputs_resp isense_get_sum_block_inputs;
+ } BPMP_UNION_ANON;
+} BPMP_ABI_PACKED;
+
+/** @} HWPM */
+/** @endcond */
+
+/** @cond (bpmp_tb500)
+ * @ingroup MRQ_Codes
+ * @def MRQ_DVFS
+ * @brief Configure DVFS functionality
+ *
+ * * Initiators: CCPLEX
+ * * Targets: BPMP
+ * * Request Payload: @ref mrq_dvfs_request
+ *
+ * @addtogroup DVFS
+ * @{
+ */
+
+/**
+ * @brief Sub-command identifiers for #MRQ_DVFS.
+ */
+enum mrq_dvfs_cmd {
+ /**
+ * @brief Check whether the BPMP-FW supports the specified
+ * #MRQ_DVFS sub-command.
+ *
+ * mrq_response:err is 0 if the specified request is
+ * supported and -#BPMP_ENODEV otherwise.
+ */
+ CMD_DVFS_QUERY_ABI = 1,
+
+ /**
+ * @brief Configure DVFS controller
+ *
+ * mrq_response:err is defined as:
+ *
+ * | Value | Description |
+ * | -------------- | ------------------------------------------- |
+ * | 0 | Success |
+ * | -#BPMP_ENODEV | #MRQ_DVFS is not supported by BPMP-FW. |
+ * | -#BPMP_ENOTSUP | Subcommand is not supported by BPMP-FW. |
+ * | -#BPMP_EINVAL | Invalid request parameters. |
+ */
+ CMD_DVFS_SET_CTRL_STATE = 2,
+
+ /**
+ * @brief Configure DVFS manager
+ *
+ * mrq_response:err is defined as:
+ *
+ * | Value | Description |
+ * | -------------- | ------------------------------------------- |
+ * | 0 | Success |
+ * | -#BPMP_ENODEV | #MRQ_DVFS is not supported by BPMP-FW. |
+ * | -#BPMP_ENOTSUP | Subcommand is not supported by BPMP-FW. |
+ * | -#BPMP_EINVAL | Invalid request parameters. |
+ */
+ CMD_DVFS_SET_MGR_STATE = 3,
+
+ /**
+ * @brief Largest supported #MRQ_DVFS sub-command identifier + 1
+ */
+ CMD_DVFS_MAX,
+};
+
+/**
+ * @brief Request data for #MRQ_DVFS sub-command #CMD_DVFS_QUERY_ABI
+ */
+struct cmd_dvfs_query_abi_req {
+ /** @brief Sub-command identifier from @ref mrq_dvfs_cmd */
+ uint32_t cmd_code;
+} BPMP_ABI_PACKED;
+
+struct cmd_dvfs_set_ctrl_state_req {
+ /** @brief Controller ID from @ref bpmp_dvfs_ctrl_ids */
+ uint32_t ctrl_id;
+ /** @brief Controller enable state */
+ uint32_t enable;
+} BPMP_ABI_PACKED;
+
+struct cmd_dvfs_set_mgr_state_req {
+ /** @brief Manager ID from @ref bpmp_dvfs_mgr_ids */
+ uint32_t mgr_id;
+ /** @brief Manager enable state */
+ uint32_t enable;
+} BPMP_ABI_PACKED;
+
+/**
+ * @brief Request payload for the #MRQ_DVFS -command
+ *
+ * | Sub-command | Request payload |
+ * | ---------------------------------------- | -------------------------------------------- |
+ * | #CMD_DVFS_QUERY_ABI | #cmd_dvfs_query_abi_req |
+ * | #CMD_DVFS_SET_CTRL_STATE | #cmd_dvfs_set_ctrl_state_req |
+ * | #CMD_DVFS_SET_MGR_STATE | #cmd_dvfs_set_mgr_state_req |
+ */
+struct mrq_dvfs_request {
+ uint32_t cmd;
+ union {
+ struct cmd_dvfs_query_abi_req query_abi;
+ struct cmd_dvfs_set_ctrl_state_req set_ctrl_state;
+ struct cmd_dvfs_set_mgr_state_req set_mgr_state;
+ } BPMP_UNION_ANON;
+} BPMP_ABI_PACKED;
+
+/** @} DVFS */
+/** @endcond */
+
+/** @cond (bpmp_tb500)
+ * @ingroup MRQ_Codes
+ * @def MRQ_PPP_PROFILE
+ * @brief Get power/performance profile configuration settings.
+ *
+ * * Initiators: Any
+ * * Targets: BPMP
+ * * Request Payload: @ref mrq_ppp_profile_request
+ * * Response Payload: @ref mrq_ppp_profile_response
+ *
+ * @addtogroup PPP
+ * @{
+ */
+
+/**
+ * @brief Sub-command identifiers for #MRQ_PPP_PROFILE.
+ */
+enum mrq_ppp_profile_cmd {
+ /**
+ * @brief Check whether the BPMP-FW supports the specified
+ * #MRQ_PPP_PROFILE sub-command.
+ *
+ * mrq_ppp_profile_response:err is 0 if the specified request is
+ * supported and -#BPMP_ENOTSUP otherwise.
+ */
+
+ CMD_PPP_PROFILE_QUERY_ABI = 0,
+ /**
+ * @brief Query the BPMP for the CPU core and SLC slice configuration associated
+ * with a given Power/Performance Profile (PPP).
+ *
+ * mrq_ppp_profile_response:err is defined as:
+ *
+ * | Value | Description |
+ * |----------------|------------------------------------------------|
+ * | 0 | Success |
+ * | -#BPMP_ENOTSUP | #MRQ_PPP_PROFILE is not supported by BPMP-FW. |
+ * | -#BPMP_EINVAL | Invalid request parameters. |
+ */
+ CMD_PPP_PROFILE_QUERY_MASKS = 1,
+ /**
+ * @brief Query BPMP for the CPU mask corresponding to a requested
+ * number of active CPU cores.
+ *
+ * mrq_ppp_profile_response:err is defined as:
+ *
+ * | Value | Description |
+ * |----------------|------------------------------------------------|
+ * | 0 | Success |
+ * | -#BPMP_ENOTSUP | #MRQ_PPP_PROFILE is not supported by BPMP-FW. |
+ * | -#BPMP_EINVAL | Invalid request parameters. |
+ */
+ CMD_PPP_CORE_QUERY_CPU_MASK = 2,
+ /**
+ * @brief Query BPMP-FW for the currently available Power/Performance Profiles.
+ *
+ * mrq_ppp_profile_response:err is defined as:
+ *
+ * | Value | Description |
+ * |----------------|------------------------------------------------|
+ * | 0 | Success |
+ * | -#BPMP_ENOTSUP | #MRQ_PPP_PROFILE is not supported by BPMP-FW. |
+ * | -#BPMP_EINVAL | Invalid request parameters. |
+ */
+ CMD_PPP_AVAILABLE_QUERY = 3,
+};
+
+/**
+ * @brief Request data for #MRQ_PPP_PROFILE sub-command
+ * #CMD_PPP_PROFILE_QUERY_ABI
+ */
+struct cmd_ppp_profile_query_abi_req {
+ /** @brief Sub-command identifier from @ref mrq_ppp_profile_cmd */
+ uint32_t cmd_code;
+} BPMP_ABI_PACKED;
+
+/**
+ * @brief Response data for #MRQ_PPP_PROFILE sub-command
+ * #CMD_PPP_AVAILABLE_QUERY
+ */
+struct cmd_ppp_available_query_resp {
+ /**
+ * @brief Bitmask of available profiles.
+ * Bit N = 1 ⇒ profile N is available
+ */
+ uint32_t avail_ppp_mask;
+} BPMP_ABI_PACKED;
+
+/**
+ * @brief Request data for #MRQ_PPP_PROFILE sub-command
+ * #CMD_PPP_PROFILE_QUERY_MASKS
+ */
+struct cmd_ppp_profile_query_masks_req {
+ /** @brief power/perf profile identifier */
+ uint32_t profile_id;
+} BPMP_ABI_PACKED;
+
+/**
+ * @brief Response payload for #MRQ_PPP_PROFILE sub-command
+ * #CMD_PPP_PROFILE_QUERY_MASKS
+ */
+struct cmd_ppp_profile_query_masks_resp {
+ /** @brief Enabled cores in this profile */
+ uint32_t num_active_cores;
+ /** @brief Enabled SLC slices in this profile */
+ uint32_t num_active_slcs;
+ /** @brief Number of valid words in active_core_masks array */
+ uint32_t max_num_core_words;
+ /** @brief Number of valid words in active_slc_masks array */
+ uint32_t max_num_slc_words;
+ /** @brief Enabled cores bit mask (bit N = 1 => core N enabled) */
+ uint32_t active_core_masks[8];
+ /** @brief Enabled SLC slices bit mask (bit N = 1 => SLC slice N enabled) */
+ uint32_t active_slc_masks[8];
+} BPMP_ABI_PACKED;
+
+/**
+ * @brief Request data for #MRQ_PPP_PROFILE sub-command
+ * #CMD_PPP_CORE_QUERY_CPU_MASK
+ */
+struct cmd_ppp_core_query_cpu_mask_req {
+ /** @brief Requested number of active cores */
+ uint32_t num_cores;
+} BPMP_ABI_PACKED;
+
+/**
+ * @brief Response data for #MRQ_PPP_PROFILE sub-command
+ * #CMD_PPP_CORE_QUERY_CPU_MASK
+ */
+struct cmd_ppp_core_query_cpu_mask_resp {
+ /** @brief Number of valid words in active_core_masks array */
+ uint32_t max_num_words;
+ /** @brief Enabled CPU core bitmask (bit N = 1 ⇒ core N enabled) */
+ uint32_t active_core_masks[8];
+} BPMP_ABI_PACKED;
+
+/**
+ * @brief Request payload for the #MRQ_PPP_PROFILE -command
+ *
+ * | Sub-command | Request payload |
+ * |-------------------------------|----------------------------------------|
+ * | #CMD_PPP_PROFILE_QUERY_ABI | #cmd_ppp_profile_query_abi_req |
+ * | #CMD_PPP_PROFILE_QUERY_MASKS | #cmd_ppp_profile_query_masks_req |
+ * | #CMD_PPP_CORE_QUERY_CPU_MASK | #cmd_ppp_core_query_cpu_mask_req |
+ * | #CMD_PPP_AVAILABLE_QUERY | - |
+ */
+struct mrq_ppp_profile_request {
+ /** @brief Sub-command ID from @ref mrq_ppp_profile_cmd. */
+ uint32_t cmd;
+ union {
+ struct cmd_ppp_profile_query_abi_req query_abi;
+ struct cmd_ppp_profile_query_masks_req ppp_profile_masks_req;
+ struct cmd_ppp_core_query_cpu_mask_req ppp_core_mask_req;
+ } BPMP_UNION_ANON;
+} BPMP_ABI_PACKED;
+
+/**
+ * @brief Response payload for the #MRQ_PPP_PROFILE -command.
+ *
+ * | Sub-command | Response payload |
+ * |-------------------------------|----------------------------------------|
+ * | #CMD_PPP_PROFILE_QUERY_ABI | - |
+ * | #CMD_PPP_PROFILE_QUERY_MASKS | #cmd_ppp_profile_query_masks_resp |
+ * | #CMD_PPP_CORE_QUERY_CPU_MASK | #cmd_ppp_core_query_cpu_mask_resp |
+ * | #CMD_PPP_AVAILABLE_QUERY | #cmd_ppp_available_query_resp |
+ */
+struct mrq_ppp_profile_response {
+ uint32_t err;
+ union {
+ struct cmd_ppp_profile_query_masks_resp ppp_profile_masks_resp;
+ struct cmd_ppp_core_query_cpu_mask_resp ppp_core_mask_resp;
+ struct cmd_ppp_available_query_resp ppp_avail_query_resp;
+ } BPMP_UNION_ANON;
+} BPMP_ABI_PACKED;
+
+/** @} PPP */
+/** @endcond */
/**
* @addtogroup Error_Codes
@@ -3953,6 +6728,8 @@ struct mrq_gears_response {
#define BPMP_ENOSYS 38
/** @brief Invalid slot */
#define BPMP_EBADSLT 57
+/** @brief No data */
+#define BPMP_ENODATA 61
/** @brief Invalid message */
#define BPMP_EBADMSG 77
/** @brief Operation not supported */
diff --git a/include/soc/tegra/bpmp.h b/include/soc/tegra/bpmp.h
index f5e4ac5b8cce..a33582590a3b 100644
--- a/include/soc/tegra/bpmp.h
+++ b/include/soc/tegra/bpmp.h
@@ -127,6 +127,7 @@ struct tegra_bpmp_message {
#if IS_ENABLED(CONFIG_TEGRA_BPMP)
struct tegra_bpmp *tegra_bpmp_get(struct device *dev);
+struct tegra_bpmp *tegra_bpmp_get_with_id(struct device *dev, unsigned int *id);
void tegra_bpmp_put(struct tegra_bpmp *bpmp);
int tegra_bpmp_transfer_atomic(struct tegra_bpmp *bpmp,
struct tegra_bpmp_message *msg);
@@ -143,21 +144,31 @@ bool tegra_bpmp_mrq_is_supported(struct tegra_bpmp *bpmp, unsigned int mrq);
#else
static inline struct tegra_bpmp *tegra_bpmp_get(struct device *dev)
{
- return ERR_PTR(-ENOTSUPP);
+ return ERR_PTR(-ENODEV);
}
+
+static inline struct tegra_bpmp *tegra_bpmp_get_with_id(struct device *dev,
+ unsigned int *id)
+{
+ return ERR_PTR(-ENODEV);
+}
+
static inline void tegra_bpmp_put(struct tegra_bpmp *bpmp)
{
}
+
static inline int tegra_bpmp_transfer_atomic(struct tegra_bpmp *bpmp,
struct tegra_bpmp_message *msg)
{
- return -ENOTSUPP;
+ return -ENODEV;
}
+
static inline int tegra_bpmp_transfer(struct tegra_bpmp *bpmp,
struct tegra_bpmp_message *msg)
{
- return -ENOTSUPP;
+ return -ENODEV;
}
+
static inline void tegra_bpmp_mrq_return(struct tegra_bpmp_channel *channel,
int code, const void *data,
size_t size)
@@ -169,8 +180,9 @@ static inline int tegra_bpmp_request_mrq(struct tegra_bpmp *bpmp,
tegra_bpmp_mrq_handler_t handler,
void *data)
{
- return -ENOTSUPP;
+ return -ENODEV;
}
+
static inline void tegra_bpmp_free_mrq(struct tegra_bpmp *bpmp,
unsigned int mrq, void *data)
{
diff --git a/include/soc/tegra/mc.h b/include/soc/tegra/mc.h
index 6ee4c59db620..e6da035d1306 100644
--- a/include/soc/tegra/mc.h
+++ b/include/soc/tegra/mc.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
- * Copyright (C) 2014 NVIDIA Corporation
+ * Copyright (C) 2014-2026 NVIDIA Corporation
*/
#ifndef __SOC_TEGRA_MC_H__
@@ -10,10 +10,11 @@
#include <linux/debugfs.h>
#include <linux/err.h>
#include <linux/interconnect-provider.h>
+#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/reset-controller.h>
-#include <linux/types.h>
#include <linux/tegra-icc.h>
+#include <linux/types.h>
struct clk;
struct device;
@@ -164,10 +165,31 @@ struct tegra_mc_ops {
int (*probe)(struct tegra_mc *mc);
void (*remove)(struct tegra_mc *mc);
int (*resume)(struct tegra_mc *mc);
- irqreturn_t (*handle_irq)(int irq, void *data);
int (*probe_device)(struct tegra_mc *mc, struct device *dev);
};
+struct tegra_mc_regs {
+ unsigned int cfg_channel_enable;
+ unsigned int err_status;
+ unsigned int err_add;
+ unsigned int err_add_hi;
+ unsigned int err_vpr_status;
+ unsigned int err_vpr_add;
+ unsigned int err_sec_status;
+ unsigned int err_sec_add;
+ unsigned int err_mts_status;
+ unsigned int err_mts_add;
+ unsigned int err_gen_co_status;
+ unsigned int err_gen_co_add;
+ unsigned int err_route_status;
+ unsigned int err_route_add;
+};
+
+struct tegra_mc_intmask {
+ u32 reg;
+ u32 mask;
+};
+
struct tegra_mc_soc {
const struct tegra_mc_client *clients;
unsigned int num_clients;
@@ -185,7 +207,6 @@ struct tegra_mc_soc {
const struct tegra_smmu_soc *smmu;
- u32 intmask;
u32 ch_intmask;
u32 global_intstatus_channel_shift;
bool has_addr_hi_reg;
@@ -196,6 +217,14 @@ struct tegra_mc_soc {
const struct tegra_mc_icc_ops *icc_ops;
const struct tegra_mc_ops *ops;
+ const struct tegra_mc_regs *regs;
+
+ const irq_handler_t *handle_irq;
+ unsigned int num_interrupts;
+ unsigned int mc_addr_hi_mask;
+ unsigned int mc_err_status_type_mask;
+ const struct tegra_mc_intmask *intmasks;
+ unsigned int num_intmasks;
};
struct tegra_mc {
@@ -206,7 +235,6 @@ struct tegra_mc {
void __iomem *bcast_ch_regs;
void __iomem **ch_regs;
struct clk *clk;
- int irq;
const struct tegra_mc_soc *soc;
unsigned long tick;
@@ -256,4 +284,6 @@ tegra_mc_get_carveout_info(struct tegra_mc *mc, unsigned int id,
}
#endif
+extern const struct tegra_mc_regs tegra20_mc_regs;
+
#endif /* __SOC_TEGRA_MC_H__ */
diff --git a/samples/qmi/qmi_sample_client.c b/samples/qmi/qmi_sample_client.c
index d1814582319b..247ec5e54c4f 100644
--- a/samples/qmi/qmi_sample_client.c
+++ b/samples/qmi/qmi_sample_client.c
@@ -592,7 +592,7 @@ static int qmi_sample_init(void)
if (ret < 0)
goto err_unregister_driver;
- qmi_add_lookup(&lookup_client, 15, 0, 0);
+ qmi_add_lookup(&lookup_client, QMI_SERVICE_ID_TEST, 0, 0);
return 0;