diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-cti b/Documentation/ABI/testing/sysfs-bus-coresight-devices-cti index a97b70f588da8..b013de5a7afc0 100644 --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-cti +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-cti @@ -239,3 +239,9 @@ Date: March 2020 KernelVersion: 5.7 Contact: Mike Leach or Mathieu Poirier Description: (Write) Clear all channel / trigger programming. + +What: /sys/bus/coresight/devices//label +Date: Feb 2025 +KernelVersion 6.15 +Contact: Mao Jinlong +Description: (Read) Show hardware context information of device. diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-funnel b/Documentation/ABI/testing/sysfs-bus-coresight-devices-funnel index d75acda5e1b38..d9780489aa123 100644 --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-funnel +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-funnel @@ -10,3 +10,9 @@ Date: November 2014 KernelVersion: 3.19 Contact: Mathieu Poirier Description: (RW) Defines input port priority order. + +What: /sys/bus/coresight/devices/.funnel/label +Date: Feb 2025 +KernelVersion 6.15 +Contact: Mao Jinlong +Description: (Read) Show hardware context information of device. diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tgu b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tgu new file mode 100644 index 0000000000000..117e648d28535 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tgu @@ -0,0 +1,51 @@ +What: /sys/bus/coresight/devices//enable_tgu +Date: February 2025 +KernelVersion 6.15 +Contact: Jinlong Mao (QUIC) , Sam Chai (QUIC) +Description: + (RW) Set/Get the enable/disable status of TGU + Accepts only one of the 2 values - 0 or 1. + 0 : disable TGU. + 1 : enable TGU. + +What: /sys/bus/coresight/devices//step[0:7]_priority[0:3]/reg[0:17] +Date: February 2025 +KernelVersion 6.15 +Contact: Jinlong Mao (QUIC) , Sam Chai (QUIC) +Description: + (RW) Set/Get the sensed signal with specific step and priority for TGU. + +What: /sys/bus/coresight/devices//step[0:7]_condition_decode/reg[0:3] +Date: February 2025 +KernelVersion 6.15 +Contact: Jinlong Mao (QUIC) , Sam Chai (QUIC) +Description: + (RW) Set/Get the decode mode with specific step for TGU. + +What: /sys/bus/coresight/devices//step[0:7]_condition_select/reg[0:3] +Date: February 2025 +KernelVersion 6.15 +Contact: Jinlong Mao (QUIC) , Sam Chai (QUIC) +Description: + (RW) Set/Get the next action with specific step for TGU. + +What: /sys/bus/coresight/devices//step[0:7]_timer/reg[0:1] +Date: February 2025 +KernelVersion 6.15 +Contact: Jinlong Mao (QUIC) , Sam Chai (QUIC) +Description: + (RW) Set/Get the timer value with specific step for TGU. + +What: /sys/bus/coresight/devices//step[0:7]_counter/reg[0:1] +Date: February 2025 +KernelVersion 6.15 +Contact: Jinlong Mao (QUIC) , Sam Chai (QUIC) +Description: + (RW) Set/Get the counter value with specific step for TGU. + +What: /sys/bus/coresight/devices//reset_tgu +Date: February 2025 +KernelVersion 6.15 +Contact: Jinlong Mao (QUIC) , Sam Chai (QUIC) +Description: + (Write) Write 1 to reset the dataset for TGU. diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm index a341b08ae70bf..29f04eebdf226 100644 --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm @@ -272,3 +272,9 @@ KernelVersion 6.15 Contact: Jinlong Mao (QUIC) , Tao Zhang (QUIC) Description: (RW) Set/Get the enablement of the individual lane. + +What: /sys/bus/coresight/devices//label +Date: Feb 2025 +KernelVersion 6.15 +Contact: Mao Jinlong +Description: (Read) Show hardware context information of device. diff --git a/Documentation/devicetree/bindings/arm/arm,coresight-cti.yaml b/Documentation/devicetree/bindings/arm/arm,coresight-cti.yaml index 2d5545a2b49c6..5ca6d3d313a3d 100644 --- a/Documentation/devicetree/bindings/arm/arm,coresight-cti.yaml +++ b/Documentation/devicetree/bindings/arm/arm,coresight-cti.yaml @@ -98,6 +98,12 @@ properties: power-domains: maxItems: 1 + label: + $ref: /schemas/types.yaml#/definitions/string + description: + Define the label which can describe what kind of HW or system the + coresight device belongs to. + arm,cti-ctm-id: $ref: /schemas/types.yaml#/definitions/uint32 description: diff --git a/Documentation/devicetree/bindings/arm/arm,coresight-dummy-sink.yaml b/Documentation/devicetree/bindings/arm/arm,coresight-dummy-sink.yaml index 08b89b62c505b..bc82cd1f3595d 100644 --- a/Documentation/devicetree/bindings/arm/arm,coresight-dummy-sink.yaml +++ b/Documentation/devicetree/bindings/arm/arm,coresight-dummy-sink.yaml @@ -39,6 +39,12 @@ properties: enum: - arm,coresight-dummy-sink + label: + $ref: /schemas/types.yaml#/definitions/string + description: + Define the label which can describe what kind of HW or system the + coresight device belongs to. + in-ports: $ref: /schemas/graph.yaml#/properties/ports diff --git a/Documentation/devicetree/bindings/arm/arm,coresight-dummy-source.yaml b/Documentation/devicetree/bindings/arm/arm,coresight-dummy-source.yaml index 742dc4e25d3bb..3010055d5ad6f 100644 --- a/Documentation/devicetree/bindings/arm/arm,coresight-dummy-source.yaml +++ b/Documentation/devicetree/bindings/arm/arm,coresight-dummy-source.yaml @@ -38,6 +38,12 @@ properties: enum: - arm,coresight-dummy-source + label: + $ref: /schemas/types.yaml#/definitions/string + description: + Define the label which can describe what kind of HW or system the + coresight device belongs to. + arm,static-trace-id: description: If dummy source needs static id support, use this to set trace id. $ref: /schemas/types.yaml#/definitions/uint32 diff --git a/Documentation/devicetree/bindings/arm/arm,coresight-dynamic-funnel.yaml b/Documentation/devicetree/bindings/arm/arm,coresight-dynamic-funnel.yaml index 44a1041cb0fc9..30776610d4b4b 100644 --- a/Documentation/devicetree/bindings/arm/arm,coresight-dynamic-funnel.yaml +++ b/Documentation/devicetree/bindings/arm/arm,coresight-dynamic-funnel.yaml @@ -57,6 +57,12 @@ properties: power-domains: maxItems: 1 + label: + $ref: /schemas/types.yaml#/definitions/string + description: + Define the label which can describe what kind of HW or system the + coresight device belongs to. + in-ports: $ref: /schemas/graph.yaml#/properties/ports diff --git a/Documentation/devicetree/bindings/arm/arm,coresight-dynamic-replicator.yaml b/Documentation/devicetree/bindings/arm/arm,coresight-dynamic-replicator.yaml index 03792e9bd97a0..178a3861ee29e 100644 --- a/Documentation/devicetree/bindings/arm/arm,coresight-dynamic-replicator.yaml +++ b/Documentation/devicetree/bindings/arm/arm,coresight-dynamic-replicator.yaml @@ -54,6 +54,12 @@ properties: - const: apb_pclk - const: atclk + label: + $ref: /schemas/types.yaml#/definitions/string + description: + Define the label which can describe what kind of HW or system the + coresight device belongs to. + power-domains: maxItems: 1 diff --git a/Documentation/devicetree/bindings/arm/arm,coresight-static-funnel.yaml b/Documentation/devicetree/bindings/arm/arm,coresight-static-funnel.yaml index cc8c3baa79b45..39b291909cc41 100644 --- a/Documentation/devicetree/bindings/arm/arm,coresight-static-funnel.yaml +++ b/Documentation/devicetree/bindings/arm/arm,coresight-static-funnel.yaml @@ -30,6 +30,12 @@ properties: power-domains: maxItems: 1 + label: + $ref: /schemas/types.yaml#/definitions/string + description: + Define the label which can describe what kind of HW or system the + coresight device belongs to. + in-ports: $ref: /schemas/graph.yaml#/properties/ports diff --git a/Documentation/devicetree/bindings/arm/arm,coresight-static-replicator.yaml b/Documentation/devicetree/bindings/arm/arm,coresight-static-replicator.yaml index 0c1017affbad2..bd0b973a5bee7 100644 --- a/Documentation/devicetree/bindings/arm/arm,coresight-static-replicator.yaml +++ b/Documentation/devicetree/bindings/arm/arm,coresight-static-replicator.yaml @@ -42,6 +42,11 @@ properties: - const: apb_pclk - const: dbg_trc - const: dbg_apb + label: + $ref: /schemas/types.yaml#/definitions/string + description: + Define the label which can describe what kind of HW or system the + coresight device belongs to. in-ports: $ref: /schemas/graph.yaml#/properties/ports diff --git a/Documentation/devicetree/bindings/arm/arm,coresight-tmc.yaml b/Documentation/devicetree/bindings/arm/arm,coresight-tmc.yaml index 4787d7c6bac2a..6a37ebaf474b2 100644 --- a/Documentation/devicetree/bindings/arm/arm,coresight-tmc.yaml +++ b/Documentation/devicetree/bindings/arm/arm,coresight-tmc.yaml @@ -55,6 +55,12 @@ properties: - const: apb_pclk - const: atclk + label: + $ref: /schemas/types.yaml#/definitions/string + description: + Define the label which can describe what kind of HW or system the + coresight device belongs to. + iommus: maxItems: 1 diff --git a/Documentation/devicetree/bindings/arm/psci.yaml b/Documentation/devicetree/bindings/arm/psci.yaml index 7360a2849b5bd..3ed573e5eb48f 100644 --- a/Documentation/devicetree/bindings/arm/psci.yaml +++ b/Documentation/devicetree/bindings/arm/psci.yaml @@ -98,6 +98,27 @@ properties: [1] Kernel documentation - ARM idle states bindings Documentation/devicetree/bindings/cpu/idle-states.yaml + reset-types: + type: object + $ref: /schemas/power/reset/reboot-mode.yaml# + unevaluatedProperties: false + properties: + # "mode-normal" is just SYSTEM_RESET + mode-normal: false + patternProperties: + "^mode-.*$": + minItems: 1 + maxItems: 2 + description: | + Describes a vendor-specific reset type. The string after "mode-" + maps a reboot mode to the parameters in the PSCI SYSTEM_RESET2 call. + + Parameters are named mode-xxx = , where xxx + is the name of the magic reboot mode, type is the lower 31 bits + of the reset_type, and, optionally, the cookie value. If the cookie + is not provided, it is defaulted to zero. + The 31st bit (vendor-resets) will be implicitly set by the driver. + patternProperties: "^power-domain-": $ref: /schemas/power/power-domain.yaml# @@ -137,6 +158,15 @@ allOf: required: - cpu_off - cpu_on + - if: + not: + properties: + compatible: + contains: + const: arm,psci-1.0 + then: + properties: + reset-types: false additionalProperties: false @@ -261,4 +291,17 @@ examples: domain-idle-states = <&cluster_ret>, <&cluster_pwrdn>; }; }; + + - |+ + + // Case 5: SYSTEM_RESET2 vendor resets + psci { + compatible = "arm,psci-1.0"; + method = "smc"; + + reset-types { + mode-edl = <0>; + mode-bootloader = <1 2>; + }; + }; ... diff --git a/Documentation/devicetree/bindings/arm/qcom,coresight-qmi.yaml b/Documentation/devicetree/bindings/arm/qcom,coresight-qmi.yaml new file mode 100644 index 0000000000000..601c865fe4d73 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/qcom,coresight-qmi.yaml @@ -0,0 +1,65 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/arm/qcom,coresight-qmi.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm coresight QMI(Qualcomm Messaging Interface) component + +description: | + Qualcomm Messaging Interface (QMI) is an interface that clients can + use to send, and receive, messages from a remote entity. The coresight + QMI component is to configure QMI instance ids and service ids for different + remote subsystem connections. Coresight QMI driver uses the ids to init + the qmi connections. Other coresight drivers call the send qmi request + function when connection is established. + +maintainers: + - Mao Jinlong + +properties: + compatible: + enum: + - qcom,coresight-qmi + +patternProperties: + '^conns(-[0-9]+)?$': + type: object + description: + QMI instance id and service id for different remote subsystem connections. + + properties: + qmi-id: + $ref: /schemas/types.yaml#/definitions/uint32 + description: + Instance id for the remote subsystem connection. + + service-id: + $ref: /schemas/types.yaml#/definitions/uint32 + description: + Service id for the remote subsystem connection. + + additionalProperties: false + + required: + - qmi-id + - service-id + +required: + - compatible + +additionalProperties: false + +examples: + # Minimum coresight qmi definition. + - | + coresight-qmi { + compatible = "qcom,coresight-qmi"; + + conns-0 { + qmi-id = <0xd>; + service-id = <0x33>; + }; + }; + +... diff --git a/Documentation/devicetree/bindings/arm/qcom,coresight-remote-etm.yaml b/Documentation/devicetree/bindings/arm/qcom,coresight-remote-etm.yaml index 4fd5752978cd0..947fe33738a3f 100644 --- a/Documentation/devicetree/bindings/arm/qcom,coresight-remote-etm.yaml +++ b/Documentation/devicetree/bindings/arm/qcom,coresight-remote-etm.yaml @@ -20,6 +20,13 @@ properties: compatible: const: qcom,coresight-remote-etm + qcom,qmi-id: + $ref: /schemas/types.yaml#/definitions/uint32 + description: + This id is used by qmi API to communicate with remote processor for + enabling and disabling remote etm. Each processor has its unique instance + id. + out-ports: $ref: /schemas/graph.yaml#/properties/ports additionalProperties: false @@ -32,6 +39,7 @@ properties: required: - compatible - out-ports + - qcom,qmi-id additionalProperties: false @@ -40,6 +48,8 @@ examples: etm { compatible = "qcom,coresight-remote-etm"; + qcom,qmi-id = <2>; + out-ports { port { modem_etm0_out_funnel_modem: endpoint { diff --git a/Documentation/devicetree/bindings/arm/qcom,coresight-tgu.yaml b/Documentation/devicetree/bindings/arm/qcom,coresight-tgu.yaml new file mode 100644 index 0000000000000..3576d38711261 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/qcom,coresight-tgu.yaml @@ -0,0 +1,92 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +# Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved. +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/arm/qcom,coresight-tgu.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Trigger Generation Unit - TGU + +description: | + The Trigger Generation Unit (TGU) is a Data Engine which can be utilized + to sense a plurality of signals and create a trigger into the CTI or + generate interrupts to processors. The TGU is like the trigger circuit + of a Logic Analyzer. The corresponding trigger logic can be realized by + configuring the conditions for each step after sensing the signal. + Once setup and enabled, it will observe sense inputs and based upon + the activity of those inputs, even over clock cycles, may detect a + preprogrammed state/sequence and then produce a trigger or interrupt. + + The primary use case of the TGU is to detect patterns or sequences on a + given set of signals within some region to indentify the issue in time + once there is abnormal behavior in the subsystem. + +maintainers: + - Mao Jinlong + - Sam Chai + +# Need a custom select here or 'arm,primecell' will match on lots of nodes +select: + properties: + compatible: + contains: + enum: + - qcom,coresight-tgu + required: + - compatible + +properties: + compatible: + items: + - const: qcom,coresight-tgu + - const: arm,primecell + + reg: + maxItems: 1 + + clocks: + maxItems: 1 + + clock-names: + items: + - const: apb_pclk + + in-ports: + $ref: /schemas/graph.yaml#/properties/ports + additionalProperties: false + + properties: + port: + description: + The port mechanism here ensures the relationship between TGU and + TPDM, as TPDM is one of the inputs for TGU. It will allow TGU to + function as TPDM's helper and enable TGU when the connected + TPDM is enabled. + $ref: /schemas/graph.yaml#/properties/port + +required: + - compatible + - reg + - clocks + - clock-names + +additionalProperties: false + +examples: + - | + tgu@10b0e000 { + compatible = "qcom,coresight-tgu", "arm,primecell"; + reg = <0x10b0e000 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + in-ports { + port { + tgu_in_tpdm_swao: endpoint{ + remote-endpoint = <&tpdm_swao_out_tgu>; + }; + }; + }; + }; +... diff --git a/Documentation/devicetree/bindings/arm/qcom,coresight-tpda.yaml b/Documentation/devicetree/bindings/arm/qcom,coresight-tpda.yaml index 5ed40f21b8eb5..f42ecb4e85399 100644 --- a/Documentation/devicetree/bindings/arm/qcom,coresight-tpda.yaml +++ b/Documentation/devicetree/bindings/arm/qcom,coresight-tpda.yaml @@ -64,6 +64,12 @@ properties: items: - const: apb_pclk + label: + $ref: /schemas/types.yaml#/definitions/string + description: + Define the label which can describe what kind of HW or system the + coresight device belongs to. + in-ports: description: | Input connections from TPDM to TPDA diff --git a/Documentation/devicetree/bindings/arm/qcom,coresight-tpdm.yaml b/Documentation/devicetree/bindings/arm/qcom,coresight-tpdm.yaml index 07d21a3617f5b..5e758476ad7f4 100644 --- a/Documentation/devicetree/bindings/arm/qcom,coresight-tpdm.yaml +++ b/Documentation/devicetree/bindings/arm/qcom,coresight-tpdm.yaml @@ -76,6 +76,12 @@ properties: minimum: 0 maximum: 32 + label: + $ref: /schemas/types.yaml#/definitions/string + description: + Define the label which can describe what kind of HW or system the + coresight device belongs to. + clocks: maxItems: 1 diff --git a/Documentation/devicetree/bindings/arm/qcom.yaml b/Documentation/devicetree/bindings/arm/qcom.yaml index 56f78f0f3803f..3b2c60af12cd0 100644 --- a/Documentation/devicetree/bindings/arm/qcom.yaml +++ b/Documentation/devicetree/bindings/arm/qcom.yaml @@ -58,6 +58,7 @@ description: | qcs8550 qcm2290 qcm6490 + qcs9075 qcs9100 qdu1000 qrb2210 @@ -961,6 +962,12 @@ properties: - qcom,sa8775p-ride-r3 - const: qcom,sa8775p + - items: + - enum: + - qcom,qcs9075-iq-9075-evk + - const: qcom,qcs9075 + - const: qcom,sa8775p + - items: - enum: - qcom,qcs9100-ride diff --git a/Documentation/devicetree/bindings/i2c/qcom,i2c-geni-qcom.yaml b/Documentation/devicetree/bindings/i2c/qcom,i2c-geni-qcom.yaml index 9f66a3bb1f80c..51534953a69cf 100644 --- a/Documentation/devicetree/bindings/i2c/qcom,i2c-geni-qcom.yaml +++ b/Documentation/devicetree/bindings/i2c/qcom,i2c-geni-qcom.yaml @@ -75,6 +75,7 @@ required: allOf: - $ref: /schemas/i2c/i2c-controller.yaml# + - $ref: /schemas/soc/qcom/qcom,se-common-props.yaml# - if: properties: compatible: diff --git a/Documentation/devicetree/bindings/pci/qcom,pcie-sa8775p.yaml b/Documentation/devicetree/bindings/pci/qcom,pcie-sa8775p.yaml index e3fa232da2ca8..510c9e1c28e10 100644 --- a/Documentation/devicetree/bindings/pci/qcom,pcie-sa8775p.yaml +++ b/Documentation/devicetree/bindings/pci/qcom,pcie-sa8775p.yaml @@ -16,7 +16,12 @@ description: properties: compatible: - const: qcom,pcie-sa8775p + oneOf: + - const: qcom,pcie-sa8775p + - items: + - enum: + - qcom,pcie-qcs8300 + - const: qcom,pcie-sa8775p reg: minItems: 6 @@ -61,11 +66,14 @@ properties: - const: global resets: - maxItems: 1 + items: + - description: PCIe controller reset + - description: PCIe link down reset reset-names: items: - - const: pci + - const: pci # PCIe core reset + - const: link_down # PCIe link down reset required: - interconnects @@ -161,8 +169,10 @@ examples: power-domains = <&gcc PCIE_0_GDSC>; - resets = <&gcc GCC_PCIE_0_BCR>; - reset-names = "pci"; + resets = <&gcc GCC_PCIE_0_BCR>, + <&gcc GCC_PCIE_0_LINK_DOWN_BCR>; + reset-names = "pci", + "link_down"; perst-gpios = <&tlmm 2 GPIO_ACTIVE_LOW>; wake-gpios = <&tlmm 0 GPIO_ACTIVE_HIGH>; diff --git a/Documentation/devicetree/bindings/pci/qcom,pcie-sm8150.yaml b/Documentation/devicetree/bindings/pci/qcom,pcie-sm8150.yaml index a604f2a79de3b..2aa012b04d935 100644 --- a/Documentation/devicetree/bindings/pci/qcom,pcie-sm8150.yaml +++ b/Documentation/devicetree/bindings/pci/qcom,pcie-sm8150.yaml @@ -16,7 +16,12 @@ description: properties: compatible: - const: qcom,pcie-sm8150 + oneOf: + - const: qcom,pcie-sm8150 + - items: + - enum: + - qcom,pcie-qcs615 + - const: qcom,pcie-sm8150 reg: minItems: 5 diff --git a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml index 2c6c9296e4c0d..10c03831f9e75 100644 --- a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml +++ b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml @@ -54,7 +54,7 @@ properties: clocks: minItems: 5 - maxItems: 7 + maxItems: 6 clock-names: minItems: 5 @@ -65,7 +65,6 @@ properties: - enum: [rchng, refgen] - const: pipe - const: pipediv2 - - const: phy_aux power-domains: maxItems: 1 @@ -176,6 +175,9 @@ allOf: contains: enum: - qcom,qcs615-qmp-gen3x1-pcie-phy + - qcom,qcs8300-qmp-gen4x2-pcie-phy + - qcom,sa8775p-qmp-gen4x2-pcie-phy + - qcom,sa8775p-qmp-gen4x4-pcie-phy - qcom,sc8280xp-qmp-gen3x1-pcie-phy - qcom,sc8280xp-qmp-gen3x2-pcie-phy - qcom,sc8280xp-qmp-gen3x4-pcie-phy @@ -191,21 +193,6 @@ allOf: clock-names: minItems: 6 - - if: - properties: - compatible: - contains: - enum: - - qcom,qcs8300-qmp-gen4x2-pcie-phy - - qcom,sa8775p-qmp-gen4x2-pcie-phy - - qcom,sa8775p-qmp-gen4x4-pcie-phy - then: - properties: - clocks: - minItems: 7 - clock-names: - minItems: 7 - - if: properties: compatible: diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,sc7280-lpass-lpi-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,sc7280-lpass-lpi-pinctrl.yaml index 08801cc4e476f..b1270124bfe38 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,sc7280-lpass-lpi-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/qcom,sc7280-lpass-lpi-pinctrl.yaml @@ -20,6 +20,16 @@ properties: reg: maxItems: 2 + clocks: + items: + - description: LPASS Core voting clock + - description: LPASS Audio voting clock + + clock-names: + items: + - const: core + - const: audio + patternProperties: "-state$": oneOf: diff --git a/Documentation/devicetree/bindings/remoteproc/qcom,sm8150-pas.yaml b/Documentation/devicetree/bindings/remoteproc/qcom,sm8150-pas.yaml index 5dcc2a32c0800..a8cddf7e2fe1a 100644 --- a/Documentation/devicetree/bindings/remoteproc/qcom,sm8150-pas.yaml +++ b/Documentation/devicetree/bindings/remoteproc/qcom,sm8150-pas.yaml @@ -15,17 +15,26 @@ description: properties: compatible: - enum: - - qcom,sc8180x-adsp-pas - - qcom,sc8180x-cdsp-pas - - qcom,sc8180x-slpi-pas - - qcom,sm8150-adsp-pas - - qcom,sm8150-cdsp-pas - - qcom,sm8150-mpss-pas - - qcom,sm8150-slpi-pas - - qcom,sm8250-adsp-pas - - qcom,sm8250-cdsp-pas - - qcom,sm8250-slpi-pas + oneOf: + - items: + - enum: + - qcom,qcs615-adsp-pas + - const: qcom,sm8150-adsp-pas + - items: + - enum: + - qcom,qcs615-cdsp-pas + - const: qcom,sm8150-cdsp-pas + - enum: + - qcom,sc8180x-adsp-pas + - qcom,sc8180x-cdsp-pas + - qcom,sc8180x-slpi-pas + - qcom,sm8150-adsp-pas + - qcom,sm8150-cdsp-pas + - qcom,sm8150-mpss-pas + - qcom,sm8150-slpi-pas + - qcom,sm8250-adsp-pas + - qcom,sm8250-cdsp-pas + - qcom,sm8250-slpi-pas reg: maxItems: 1 @@ -62,16 +71,17 @@ allOf: - if: properties: compatible: - enum: - - qcom,sc8180x-adsp-pas - - qcom,sc8180x-cdsp-pas - - qcom,sc8180x-slpi-pas - - qcom,sm8150-adsp-pas - - qcom,sm8150-cdsp-pas - - qcom,sm8150-slpi-pas - - qcom,sm8250-adsp-pas - - qcom,sm8250-cdsp-pas - - qcom,sm8250-slpi-pas + contains: + enum: + - qcom,sc8180x-adsp-pas + - qcom,sc8180x-cdsp-pas + - qcom,sc8180x-slpi-pas + - qcom,sm8150-adsp-pas + - qcom,sm8150-cdsp-pas + - qcom,sm8150-slpi-pas + - qcom,sm8250-adsp-pas + - qcom,sm8250-cdsp-pas + - qcom,sm8250-slpi-pas then: properties: interrupts: @@ -88,12 +98,13 @@ allOf: - if: properties: compatible: - enum: - - qcom,sc8180x-adsp-pas - - qcom,sc8180x-cdsp-pas - - qcom,sm8150-adsp-pas - - qcom,sm8150-cdsp-pas - - qcom,sm8250-cdsp-pas + contains: + enum: + - qcom,sc8180x-adsp-pas + - qcom,sc8180x-cdsp-pas + - qcom,sm8150-adsp-pas + - qcom,sm8150-cdsp-pas + - qcom,sm8250-cdsp-pas then: properties: power-domains: diff --git a/Documentation/devicetree/bindings/serial/qcom,serial-geni-qcom.yaml b/Documentation/devicetree/bindings/serial/qcom,serial-geni-qcom.yaml index dd33794b3534e..ed7b3909d87df 100644 --- a/Documentation/devicetree/bindings/serial/qcom,serial-geni-qcom.yaml +++ b/Documentation/devicetree/bindings/serial/qcom,serial-geni-qcom.yaml @@ -12,6 +12,7 @@ maintainers: allOf: - $ref: /schemas/serial/serial.yaml# + - $ref: /schemas/soc/qcom/qcom,se-common-props.yaml# properties: compatible: diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,se-common-props.yaml b/Documentation/devicetree/bindings/soc/qcom/qcom,se-common-props.yaml new file mode 100644 index 0000000000000..044eea4bb960a --- /dev/null +++ b/Documentation/devicetree/bindings/soc/qcom/qcom,se-common-props.yaml @@ -0,0 +1,26 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/soc/qcom/qcom,se-common-props.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: QUP Peripheral-specific properties for I2C, SPI and SERIAL bus + +description: + The Generic Interface (GENI) based Qualcomm Universal Peripheral (QUP) is + a programmable module that supports a wide range of serial interfaces + such as UART, SPI, I2C, I3C, etc. This defines the common properties used + across QUP-supported peripherals. + +maintainers: + - Mukesh Kumar Savaliya + - Viken Dadhaniya + +properties: + qcom,enable-gsi-dma: + $ref: /schemas/types.yaml#/definitions/flag + description: + Configure the Serial Engine (SE) to transfer data in QCOM GPI DMA mode. + By default, FIFO mode (PIO/CPU DMA) will be selected. + +additionalProperties: true diff --git a/Documentation/devicetree/bindings/sound/qcom,lpass-va-macro.yaml b/Documentation/devicetree/bindings/sound/qcom,lpass-va-macro.yaml index f41deaa6f4df5..92b97c2140606 100644 --- a/Documentation/devicetree/bindings/sound/qcom,lpass-va-macro.yaml +++ b/Documentation/devicetree/bindings/sound/qcom,lpass-va-macro.yaml @@ -78,10 +78,16 @@ allOf: then: properties: clocks: - maxItems: 1 + minItems: 1 + maxItems: 3 clock-names: - items: - - const: mclk + oneOf: + - items: # for ADSP based platforms + - const: mclk + - const: macro + - const: dcodec + - items: # for ADSP bypass based platforms + - const: mclk - if: properties: diff --git a/Documentation/devicetree/bindings/sound/qcom,lpass-wsa-macro.yaml b/Documentation/devicetree/bindings/sound/qcom,lpass-wsa-macro.yaml index 9082e363c7094..6a999ed484e7b 100644 --- a/Documentation/devicetree/bindings/sound/qcom,lpass-wsa-macro.yaml +++ b/Documentation/devicetree/bindings/sound/qcom,lpass-wsa-macro.yaml @@ -35,11 +35,11 @@ properties: const: 0 clocks: - minItems: 4 + minItems: 3 maxItems: 6 clock-names: - minItems: 4 + minItems: 3 maxItems: 6 clock-output-names: @@ -59,12 +59,30 @@ required: allOf: - $ref: dai-common.yaml# - - if: properties: compatible: enum: - qcom,sc7280-lpass-wsa-macro + then: + properties: + clock-names: + oneOf: + - items: # for ADSP based platforms + - const: mclk + - const: npl + - const: macro + - const: dcodec + - const: fsgen + - items: # for ADSP bypass based platforms + - const: mclk + - const: npl + - const: fsgen + + - if: + properties: + compatible: + enum: - qcom,sm8250-lpass-wsa-macro - qcom,sm8450-lpass-wsa-macro - qcom,sc8280xp-lpass-wsa-macro diff --git a/Documentation/devicetree/bindings/spi/qcom,spi-geni-qcom.yaml b/Documentation/devicetree/bindings/spi/qcom,spi-geni-qcom.yaml index 2e20ca313ec1d..d12c5a060ed00 100644 --- a/Documentation/devicetree/bindings/spi/qcom,spi-geni-qcom.yaml +++ b/Documentation/devicetree/bindings/spi/qcom,spi-geni-qcom.yaml @@ -25,6 +25,7 @@ description: allOf: - $ref: /schemas/spi/spi-controller.yaml# + - $ref: /schemas/soc/qcom/qcom,se-common-props.yaml# properties: compatible: diff --git a/Documentation/devicetree/bindings/sram/qcom,imem.yaml b/Documentation/devicetree/bindings/sram/qcom,imem.yaml index 2711f90d9664b..dc3b5a69b9254 100644 --- a/Documentation/devicetree/bindings/sram/qcom,imem.yaml +++ b/Documentation/devicetree/bindings/sram/qcom,imem.yaml @@ -22,6 +22,7 @@ properties: - qcom,msm8974-imem - qcom,msm8976-imem - qcom,qcs404-imem + - qcom,qcs615-imem - qcom,qcs8300-imem - qcom,qdu1000-imem - qcom,sa8775p-imem diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile index 669b888b27a1d..77501a13d91e0 100644 --- a/arch/arm64/boot/dts/qcom/Makefile +++ b/arch/arm64/boot/dts/qcom/Makefile @@ -124,6 +124,7 @@ dtb-$(CONFIG_ARCH_QCOM) += qcs6490-rb3gen2-industrial-mezzanine.dtb dtb-$(CONFIG_ARCH_QCOM) += qcs6490-rb3gen2-vision-mezzanine.dtb dtb-$(CONFIG_ARCH_QCOM) += qcs8300-ride.dtb dtb-$(CONFIG_ARCH_QCOM) += qcs8550-aim300-aiot.dtb +dtb-$(CONFIG_ARCH_QCOM) += qcs9075-iq-9075-evk.dtb dtb-$(CONFIG_ARCH_QCOM) += qcs9100-ride.dtb dtb-$(CONFIG_ARCH_QCOM) += qcs9100-ride-r3.dtb dtb-$(CONFIG_ARCH_QCOM) += qdu1000-idp.dtb diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi index ede851fbf6284..26fab7626c394 100644 --- a/arch/arm64/boot/dts/qcom/msm8996.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi @@ -40,6 +40,15 @@ }; }; + coresight-qmi { + compatible = "qcom,coresight-qmi"; + + conns-0 { + qmi-id = <0x2>; + service-id = <0x33>; + }; + }; + cpus { #address-cells = <2>; #size-cells = <0>; @@ -448,6 +457,8 @@ etm { compatible = "qcom,coresight-remote-etm"; + qcom,qmi-id = <0x2>; + out-ports { port { modem_etm_out_funnel_in2: endpoint { diff --git a/arch/arm64/boot/dts/qcom/qcm6490-idp.dts b/arch/arm64/boot/dts/qcom/qcm6490-idp.dts index 7a155ef6492e1..923f90ca38d75 100644 --- a/arch/arm64/boot/dts/qcom/qcm6490-idp.dts +++ b/arch/arm64/boot/dts/qcom/qcm6490-idp.dts @@ -18,6 +18,7 @@ #include "pm7325.dtsi" #include "pm8350c.dtsi" #include "pmk8350.dtsi" +#include "qcs6490-audioreach.dtsi" /delete-node/ &ipa_fw_mem; /delete-node/ &rmtfs_mem; @@ -169,6 +170,30 @@ regulator-min-microvolt = <3700000>; regulator-max-microvolt = <3700000>; }; + + wcd9370: audio-codec-0 { + compatible = "qcom,wcd9370-codec"; + + pinctrl-0 = <&wcd_default>; + pinctrl-names = "default"; + + reset-gpios = <&tlmm 83 GPIO_ACTIVE_HIGH>; + + vdd-buck-supply = <&vreg_l17b_1p7>; + vdd-rxtx-supply = <&vreg_l18b_1p8>; + vdd-px-supply = <&vreg_l18b_1p8>; + vdd-mic-bias-supply = <&vreg_bob_3p296>; + + qcom,micbias1-microvolt = <1800000>; + qcom,micbias2-microvolt = <1800000>; + qcom,micbias3-microvolt = <1800000>; + qcom,micbias4-microvolt = <1800000>; + + qcom,rx-device = <&wcd937x_rx>; + qcom,tx-device = <&wcd937x_tx>; + + #sound-dai-cells = <1>; + }; }; &apps_rsc { @@ -536,6 +561,22 @@ firmware-name = "qcom/qcm6490/a660_zap.mbn"; }; +&lpass_rx_macro { + status = "okay"; +}; + +&lpass_tx_macro { + status = "okay"; +}; + +&lpass_va_macro { + status = "okay"; +}; + +&lpass_wsa_macro { + status = "okay"; +}; + &mdss { status = "okay"; }; @@ -654,6 +695,13 @@ status = "okay"; }; +&psci { + reset-types { + mode-bootloader = <0x10001 0x2>; + mode-edl = <0 0x1>; + }; +}; + &qupv3_id_0 { status = "okay"; }; @@ -716,6 +764,138 @@ cd-gpios = <&tlmm 91 GPIO_ACTIVE_LOW>; }; +&sound { + compatible = "qcom,qcm6490-idp-sndcard"; + model = "qcm6490-idp-snd-card"; + + audio-routing = "SpkrLeft IN", "WSA_SPK1 OUT", + "SpkrRight IN", "WSA_SPK2 OUT", + "IN1_HPHL", "HPHL_OUT", + "IN2_HPHR", "HPHR_OUT", + "AMIC2", "MIC BIAS2", + "TX DMIC0", "MIC BIAS1", + "TX DMIC1", "MIC BIAS2", + "TX DMIC2", "MIC BIAS3", + "TX SWR_ADC1", "ADC2_OUTPUT", + "VA DMIC0", "VA MIC BIAS3", + "VA DMIC1", "VA MIC BIAS3", + "VA DMIC2", "VA MIC BIAS1", + "VA DMIC3", "VA MIC BIAS1"; + + wsa-dai-link { + link-name = "WSA Playback"; + + codec { + sound-dai = <&left_spkr>, <&right_spkr>, + <&swr2 0>, <&lpass_wsa_macro 0>; + }; + + cpu { + sound-dai = <&q6apmbedai WSA_CODEC_DMA_RX_0>; + }; + + platform { + sound-dai = <&q6apm>; + }; + }; + + wcd-playback-dai-link { + link-name = "WCD Playback"; + + codec { + sound-dai = <&wcd9370 0>, <&swr0 0>, <&lpass_rx_macro 0>; + }; + + cpu { + sound-dai = <&q6apmbedai RX_CODEC_DMA_RX_0>; + }; + + platform { + sound-dai = <&q6apm>; + }; + }; + + wcd-capture-dai-link { + link-name = "WCD Capture"; + + codec { + sound-dai = <&wcd9370 1>, <&swr1 0>, <&lpass_tx_macro 0>; + }; + + cpu { + sound-dai = <&q6apmbedai TX_CODEC_DMA_TX_3>; + }; + + platform { + sound-dai = <&q6apm>; + }; + }; + + va-dai-link { + link-name = "VA Capture"; + + codec { + sound-dai = <&lpass_va_macro 0>; + }; + + cpu { + sound-dai = <&q6apmbedai VA_CODEC_DMA_TX_0>; + }; + + platform { + sound-dai = <&q6apm>; + }; + }; +}; + +&swr0 { + status = "okay"; + + wcd937x_rx: codec@0,4 { + compatible = "sdw20217010a00"; + reg = <0 4>; + qcom,rx-port-mapping = <1 2 3 4 5>; + qcom,rx-channel-mapping = /bits/ 8 <1 2 1 1 2 1 1 2>; + }; +}; + +&swr1 { + status = "okay"; + + wcd937x_tx: codec@0,3 { + compatible = "sdw20217010a00"; + reg = <0 3>; + qcom,tx-port-mapping = <1 1 2 3>; + qcom,tx-channel-mapping = /bits/ 8 <1 2 1 1 2 3 3 4 1 2 3 4>; + }; +}; + +&swr2 { + status = "okay"; + + left_spkr: speaker@0,1 { + compatible = "sdw10217020200"; + reg = <0 1>; + powerdown-gpios = <&tlmm 63 GPIO_ACTIVE_LOW>; + #sound-dai-cells = <0>; + sound-name-prefix = "SpkrLeft"; + #thermal-sensor-cells = <0>; + vdd-supply = <&vreg_l18b_1p8>; + qcom,port-mapping = <1 2 3 7>; + }; + + right_spkr: speaker@0,2 { + compatible = "sdw10217020200"; + reg = <0 2>; + powerdown-gpios = <&tlmm 62 GPIO_ACTIVE_LOW>; + #sound-dai-cells = <0>; + sound-name-prefix = "SpkrRight"; + #thermal-sensor-cells = <0>; + vdd-supply = <&vreg_l18b_1p8>; + qcom,port-mapping = <4 5 6 8>; + }; +}; + &tlmm { gpio-reserved-ranges = <32 2>, /* ADSP */ <48 4>; /* NFC */ @@ -725,6 +905,13 @@ function = "gpio"; bias-pull-up; }; + + wcd_default: wcd-reset-n-active-state { + pins = "gpio83"; + function = "gpio"; + drive-strength = <16>; + bias-disable; + }; }; &uart5 { diff --git a/arch/arm64/boot/dts/qcom/qcs615-ride.dts b/arch/arm64/boot/dts/qcom/qcs615-ride.dts index 2b5aa3c668676..379c8dfcac20b 100644 --- a/arch/arm64/boot/dts/qcom/qcs615-ride.dts +++ b/arch/arm64/boot/dts/qcom/qcs615-ride.dts @@ -211,12 +211,83 @@ }; }; +ðernet { + pinctrl-0 = <ðernet_defaults>; + pinctrl-names = "default"; + + phy-handle = <&rgmii_phy>; + phy-mode = "rgmii-id"; + qcom,rx-prog-swap; + + snps,mtl-rx-config = <&mtl_rx_setup>; + snps,mtl-tx-config = <&mtl_tx_setup>; + + status = "okay"; + + mdio { + compatible = "snps,dwmac-mdio"; + #address-cells = <1>; + #size-cells = <0>; + + rgmii_phy: phy@7 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <0x7>; + + interrupts-extended = <&tlmm 121 IRQ_TYPE_EDGE_FALLING>; + device_type = "ethernet-phy"; + reset-gpios = <&tlmm 104 GPIO_ACTIVE_LOW>; + reset-assert-us = <11000>; + reset-deassert-us = <70000>; + }; + }; + + mtl_rx_setup: rx-queues-config { + snps,rx-queues-to-use = <1>; + snps,rx-sched-sp; + + queue0 { + snps,dcb-algorithm; + snps,map-to-dma-channel = <0x0>; + snps,route-up; + snps,priority = <0x1>; + }; + }; + + mtl_tx_setup: tx-queues-config { + snps,tx-queues-to-use = <1>; + snps,tx-sched-wrr; + + queue0 { + snps,weight = <0x10>; + snps,dcb-algorithm; + snps,priority = <0x0>; + }; + }; +}; + &gcc { clocks = <&rpmhcc RPMH_CXO_CLK>, <&rpmhcc RPMH_CXO_CLK_A>, <&sleep_clk>; }; +&pcie { + perst-gpios = <&tlmm 101 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 100 GPIO_ACTIVE_HIGH>; + + pinctrl-0 = <&pcie_default_state>; + pinctrl-names = "default"; + + status = "okay"; +}; + +&pcie_phy { + vdda-phy-supply = <&vreg_l5a>; + vdda-pll-supply = <&vreg_l12a>; + + status = "okay"; +}; + &pm8150_gpios { usb2_en: usb2-en-state { pins = "gpio10"; @@ -240,10 +311,47 @@ status = "okay"; }; +&remoteproc_adsp { + firmware-name = "qcom/qcs615/adsp.mbn"; + + status = "okay"; +}; + +&remoteproc_cdsp { + firmware-name = "qcom/qcs615/cdsp.mbn"; + + status = "okay"; +}; + &rpmhcc { clocks = <&xo_board_clk>; }; +&tlmm { + pcie_default_state: pcie-default-state { + clkreq-pins { + pins = "gpio90"; + function = "pcie_clk_req"; + drive-strength = <2>; + bias-pull-up; + }; + + perst-pins { + pins = "gpio101"; + function = "gpio"; + drive-strength = <2>; + bias-pull-down; + }; + + wake-pins { + pins = "gpio100"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; + }; +}; + &sdhc_1 { pinctrl-0 = <&sdc1_state_on>; pinctrl-1 = <&sdc1_state_off>; @@ -278,6 +386,57 @@ status = "okay"; }; +&tlmm { + ethernet_defaults: ethernet-defaults-state { + mdc-pins { + pins = "gpio113"; + function = "rgmii"; + bias-pull-up; + }; + + mdio-pins { + pins = "gpio114"; + function = "rgmii"; + bias-pull-up; + }; + + rgmii-rx-pins { + pins = "gpio81", "gpio82", "gpio83", "gpio102", "gpio103", "gpio112"; + function = "rgmii"; + bias-disable; + drive-strength = <2>; + }; + + rgmii-tx-pins { + pins = "gpio92", "gpio93", "gpio94", "gpio95", "gpio96", "gpio97"; + function = "rgmii"; + bias-pull-up; + drive-strength = <16>; + }; + + phy-intr-pins { + pins = "gpio121"; + function = "gpio"; + bias-disable; + drive-strength = <8>; + }; + + phy-reset-pins { + pins = "gpio104"; + function = "gpio"; + bias-pull-up; + drive-strength = <16>; + }; + + pps-pins { + pins = "gpio91"; + function = "rgmii"; + bias-disable; + drive-strength = <8>; + }; + }; +}; + &uart0 { status = "okay"; }; diff --git a/arch/arm64/boot/dts/qcom/qcs615.dtsi b/arch/arm64/boot/dts/qcom/qcs615.dtsi index bb8b6c3ebd03f..dbc839363775c 100644 --- a/arch/arm64/boot/dts/qcom/qcs615.dtsi +++ b/arch/arm64/boot/dts/qcom/qcs615.dtsi @@ -332,6 +332,50 @@ qcom,bcm-voters = <&apps_bcm_voter>; }; + smp2p-adsp { + compatible = "qcom,smp2p"; + qcom,smem = <443>, <429>; + interrupts = ; + /* On this platform, bit 26 (normally SLPI) is repurposed for ADSP */ + mboxes = <&apss_shared 26>; + + qcom,local-pid = <0>; + qcom,remote-pid = <2>; + + adsp_smp2p_out: master-kernel { + qcom,entry-name = "master-kernel"; + #qcom,smem-state-cells = <1>; + }; + + adsp_smp2p_in: slave-kernel { + qcom,entry-name = "slave-kernel"; + interrupt-controller; + #interrupt-cells = <2>; + }; + }; + + smp2p-cdsp { + compatible = "qcom,smp2p"; + qcom,smem = <94>, <432>; + interrupts = ; + mboxes = <&apss_shared 6>; + + qcom,local-pid = <0>; + qcom,remote-pid = <5>; + + cdsp_smp2p_out: master-kernel { + qcom,entry-name = "master-kernel"; + #qcom,smem-state-cells = <1>; + }; + + cdsp_smp2p_in: slave-kernel { + qcom,entry-name = "slave-kernel"; + interrupt-controller; + #interrupt-cells = <2>; + }; + + }; + qup_opp_table: opp-table-qup { compatible = "operating-points-v2"; opp-shared; @@ -429,6 +473,16 @@ no-map; hwlocks = <&tcsr_mutex 3>; }; + + rproc_cdsp_mem: rproc-cdsp@93b00000 { + reg = <0x0 0x93b00000 0x0 0x1e00000>; + no-map; + }; + + rproc_adsp_mem: rproc-adsp@95900000 { + reg = <0x0 0x95900000 0x0 0x1e00000>; + no-map; + }; }; soc: soc@0 { @@ -438,6 +492,40 @@ #address-cells = <2>; #size-cells = <2>; + ethernet: ethernet@20000 { + compatible = "qcom,qcs615-ethqos", "qcom,qcs404-ethqos"; + reg = <0x0 0x00020000 0x0 0x10000>, + <0x0 0x00036000 0x0 0x100>; + reg-names = "stmmaceth", + "rgmii"; + + clocks = <&gcc GCC_EMAC_AXI_CLK>, + <&gcc GCC_EMAC_SLV_AHB_CLK>, + <&gcc GCC_EMAC_PTP_CLK>, + <&gcc GCC_EMAC_RGMII_CLK>; + clock-names = "stmmaceth", + "pclk", + "ptp_ref", + "rgmii"; + + interrupts = , + ; + interrupt-names = "macirq", + "eth_lpi"; + + power-domains = <&gcc EMAC_GDSC>; + resets = <&gcc GCC_EMAC_BCR>; + + iommus = <&apps_smmu 0x1c0 0x0>; + + snps,tso; + snps,pbl = <32>; + rx-fifo-depth = <16384>; + tx-fifo-depth = <20480>; + + status = "disabled"; + }; + gcc: clock-controller@100000 { compatible = "qcom,qcs615-gcc"; reg = <0 0x00100000 0 0x1f0000>; @@ -1012,6 +1100,144 @@ qcom,bcm-voters = <&apps_bcm_voter>; }; + pcie: pcie@1c08000 { + device_type = "pci"; + compatible = "qcom,pcie-qcs615", "qcom,pcie-sm8150"; + reg = <0x0 0x01c08000 0x0 0x3000>, + <0x0 0x40000000 0x0 0xf1d>, + <0x0 0x40000f20 0x0 0xa8>, + <0x0 0x40001000 0x0 0x1000>, + <0x0 0x40100000 0x0 0x100000>, + <0x0 0x01c0b000 0x0 0x1000>; + reg-names = "parf", + "dbi", + "elbi", + "atu", + "config", + "mhi"; + #address-cells = <3>; + #size-cells = <2>; + ranges = <0x01000000 0x0 0x00000000 0x0 0x40200000 0x0 0x100000>, + <0x02000000 0x0 0x40300000 0x0 0x40300000 0x0 0x1fd00000>; + bus-range = <0x00 0xff>; + + dma-coherent; + + linux,pci-domain = <0>; + num-lanes = <1>; + + interrupts = , + , + , + , + , + , + , + , + ; + interrupt-names = "msi0", + "msi1", + "msi2", + "msi3", + "msi4", + "msi5", + "msi6", + "msi7", + "global"; + + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0x7>; + interrupt-map = <0 0 0 1 &intc GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 2 &intc GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 3 &intc GIC_SPI 151 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 4 &intc GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_PCIE_0_PIPE_CLK>, + <&gcc GCC_PCIE_0_AUX_CLK>, + <&gcc GCC_PCIE_0_CFG_AHB_CLK>, + <&gcc GCC_PCIE_0_MSTR_AXI_CLK>, + <&gcc GCC_PCIE_0_SLV_AXI_CLK>, + <&gcc GCC_PCIE_0_SLV_Q2A_AXI_CLK>; + clock-names = "pipe", + "aux", + "cfg", + "bus_master", + "bus_slave", + "slave_q2a"; + assigned-clocks = <&gcc GCC_PCIE_0_AUX_CLK>; + assigned-clock-rates = <19200000>; + + interconnects = <&aggre1_noc MASTER_PCIE QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_PCIE_0 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "pcie-mem", "cpu-pcie"; + + iommu-map = <0x0 &apps_smmu 0x400 0x1>, + <0x100 &apps_smmu 0x401 0x1>; + + resets = <&gcc GCC_PCIE_0_BCR>; + reset-names = "pci"; + + power-domains = <&gcc PCIE_0_GDSC>; + + phys = <&pcie_phy>; + phy-names = "pciephy"; + + max-link-speed = <2>; + + operating-points-v2 = <&pcie_opp_table>; + + status = "disabled"; + + pcie_opp_table: opp-table { + compatible = "operating-points-v2"; + + /* GEN 1 x1 */ + opp-2500000 { + opp-hz = /bits/ 64 <2500000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <250000 1>; + }; + + /* GEN 2 x1 */ + opp-5000000 { + opp-hz = /bits/ 64 <5000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <500000 1>; + }; + }; + }; + + pcie_phy: phy@1c0e000 { + compatible = "qcom,qcs615-qmp-gen3x1-pcie-phy"; + reg = <0x0 0x01c0e000 0x0 0x1000>; + + clocks = <&gcc GCC_PCIE_PHY_AUX_CLK>, + <&gcc GCC_PCIE_0_CFG_AHB_CLK>, + <&gcc GCC_PCIE_0_CLKREF_CLK>, + <&gcc GCC_PCIE0_PHY_REFGEN_CLK>, + <&gcc GCC_PCIE_0_PIPE_CLK>; + clock-names = "aux", + "cfg_ahb", + "ref", + "refgen", + "pipe"; + + resets = <&gcc GCC_PCIE_0_PHY_BCR>; + reset-names = "phy"; + + assigned-clocks = <&gcc GCC_PCIE0_PHY_REFGEN_CLK>; + assigned-clock-rates = <100000000>; + + #clock-cells = <0>; + clock-output-names = "pcie_0_pipe_clk"; + + #phy-cells = <0>; + + status = "disabled"; + }; + ufs_mem_hc: ufshc@1d84000 { compatible = "qcom,qcs615-ufshc", "qcom,ufshc", "jedec,ufs-2.0"; reg = <0x0 0x01d84000 0x0 0x3000>, @@ -3073,6 +3299,44 @@ clock-names = "apb_pclk"; }; + remoteproc_cdsp: remoteproc@8300000 { + compatible = "qcom,qcs615-cdsp-pas", "qcom,sm8150-cdsp-pas"; + reg = <0x0 0x08300000 0x0 0x4040>; + + interrupts-extended = <&intc GIC_SPI 578 IRQ_TYPE_EDGE_RISING>, + <&cdsp_smp2p_in 0 IRQ_TYPE_EDGE_RISING>, + <&cdsp_smp2p_in 1 IRQ_TYPE_EDGE_RISING>, + <&cdsp_smp2p_in 2 IRQ_TYPE_EDGE_RISING>, + <&cdsp_smp2p_in 3 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "wdog", + "fatal", + "ready", + "handover", + "stop-ack"; + + clocks = <&rpmhcc RPMH_CXO_CLK>; + clock-names = "xo"; + + power-domains = <&rpmhpd RPMHPD_CX>; + power-domain-names = "cx"; + + memory-region = <&rproc_cdsp_mem>; + + qcom,qmp = <&aoss_qmp>; + + qcom,smem-states = <&cdsp_smp2p_out 0>; + qcom,smem-state-names = "stop"; + + status = "disabled"; + + glink-edge { + interrupts = ; + mboxes = <&apss_shared 4>; + label = "cdsp"; + qcom,remote-pid = <5>; + }; + }; + pmu@90b6300 { compatible = "qcom,qcs615-cpu-bwmon", "qcom,sdm845-bwmon"; reg = <0x0 0x090b6300 0x0 0x600>; @@ -3245,6 +3509,20 @@ reg = <0x0 0x0c3f0000 0x0 0x400>; }; + sram@14680000 { + compatible = "qcom,qcs615-imem", "syscon", "simple-mfd"; + reg = <0x0 0x14680000 0x0 0x2c000>; + ranges = <0 0 0x14680000 0x2c000>; + + #address-cells = <1>; + #size-cells = <1>; + + pil-reloc@2a94c { + compatible = "qcom,pil-reloc-info"; + reg = <0x2a94c 0xc8>; + }; + }; + apps_smmu: iommu@15000000 { compatible = "qcom,qcs615-smmu-500", "qcom,smmu-500", "arm,mmu-500"; reg = <0x0 0x15000000 0x0 0x80000>; @@ -3692,6 +3970,44 @@ maximum-speed = "high-speed"; }; }; + + remoteproc_adsp: remoteproc@62400000 { + compatible = "qcom,qcs615-adsp-pas", "qcom,sm8150-adsp-pas"; + reg = <0x0 0x62400000 0x0 0x4040>; + + interrupts-extended = <&intc GIC_SPI 162 IRQ_TYPE_EDGE_RISING>, + <&adsp_smp2p_in 0 IRQ_TYPE_EDGE_RISING>, + <&adsp_smp2p_in 1 IRQ_TYPE_EDGE_RISING>, + <&adsp_smp2p_in 2 IRQ_TYPE_EDGE_RISING>, + <&adsp_smp2p_in 3 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "wdog", + "fatal", + "ready", + "handover", + "stop-ack"; + + clocks = <&rpmhcc RPMH_CXO_CLK>; + clock-names = "xo"; + + power-domains = <&rpmhpd RPMHPD_CX>; + power-domain-names = "cx"; + + memory-region = <&rproc_adsp_mem>; + + qcom,qmp = <&aoss_qmp>; + + qcom,smem-states = <&adsp_smp2p_out 0>; + qcom,smem-state-names = "stop"; + + status = "disabled"; + + glink_edge: glink-edge { + interrupts = ; + mboxes = <&apss_shared 24>; + label = "lpass"; + qcom,remote-pid = <2>; + }; + }; }; arch_timer: timer { diff --git a/arch/arm64/boot/dts/qcom/qcs6490-audioreach.dtsi b/arch/arm64/boot/dts/qcom/qcs6490-audioreach.dtsi new file mode 100644 index 0000000000000..2e75e7706fb4f --- /dev/null +++ b/arch/arm64/boot/dts/qcom/qcs6490-audioreach.dtsi @@ -0,0 +1,158 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * qcs6490 device tree source for Audioreach Solution. + * This file will handle the common audio device tree nodes. + * + * Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#include +#include +#include +#include + +&lpass_dmic01_clk { + drive-strength = <8>; + bias-disable; +}; + +&lpass_dmic01_data { + bias-pull-down; +}; + +&lpass_dmic23_clk { + drive-strength = <8>; + bias-disable; +}; + +&lpass_dmic23_data { + bias-pull-down; +}; + +&lpass_rx_swr_clk { + drive-strength = <2>; + slew-rate = <1>; + bias-disable; +}; + +&lpass_rx_swr_data { + drive-strength = <2>; + slew-rate = <1>; + bias-bus-hold; +}; + +&lpass_tx_swr_clk { + drive-strength = <2>; + slew-rate = <1>; + bias-disable; +}; + +&lpass_tx_swr_data { + drive-strength = <2>; + slew-rate = <1>; + bias-bus-hold; +}; + +&lpass_rx_macro { + /delete-property/ power-domains; + /delete-property/ power-domain-names; + clocks = <&q6prmcc LPASS_CLK_ID_TX_CORE_MCLK LPASS_CLK_ATTRIBUTE_COUPLE_NO>, + <&q6prmcc LPASS_CLK_ID_TX_CORE_NPL_MCLK LPASS_CLK_ATTRIBUTE_COUPLE_NO>, + <&q6prmcc LPASS_HW_MACRO_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>, + <&q6prmcc LPASS_HW_DCODEC_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>, + <&lpass_va_macro>; + clock-names = "mclk", + "npl", + "macro", + "dcodec", + "fsgen"; +}; + +&lpass_tlmm { + clocks = <&q6prmcc LPASS_HW_MACRO_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>, + <&q6prmcc LPASS_HW_DCODEC_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>; + clock-names = "core", + "audio"; +}; + +&lpass_tx_macro { + /delete-property/ power-domains; + /delete-property/ power-domain-names; + clocks = <&q6prmcc LPASS_CLK_ID_TX_CORE_MCLK LPASS_CLK_ATTRIBUTE_COUPLE_NO>, + <&q6prmcc LPASS_CLK_ID_TX_CORE_NPL_MCLK LPASS_CLK_ATTRIBUTE_COUPLE_NO>, + <&q6prmcc LPASS_HW_MACRO_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>, + <&q6prmcc LPASS_HW_DCODEC_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>, + <&lpass_va_macro>; + clock-names = "mclk", + "npl", + "macro", + "dcodec", + "fsgen"; +}; + +&lpass_va_macro { + /delete-property/ power-domains; + /delete-property/ power-domain-names; + clocks = <&q6prmcc LPASS_CLK_ID_VA_CORE_MCLK LPASS_CLK_ATTRIBUTE_COUPLE_NO>, + <&q6prmcc LPASS_HW_MACRO_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>, + <&q6prmcc LPASS_HW_DCODEC_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>; + clock-names = "mclk", + "macro", + "dcodec"; +}; + +&lpass_wsa_macro { + /delete-property/ power-domains; + /delete-property/ power-domain-names; + clocks = <&q6prmcc LPASS_CLK_ID_TX_CORE_MCLK LPASS_CLK_ATTRIBUTE_COUPLE_NO>, + <&q6prmcc LPASS_CLK_ID_TX_CORE_NPL_MCLK LPASS_CLK_ATTRIBUTE_COUPLE_NO>, + <&q6prmcc LPASS_HW_MACRO_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>, + <&q6prmcc LPASS_HW_DCODEC_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>, + <&lpass_va_macro>; + clock-names = "mclk", + "npl", + "macro", + "dcodec", + "fsgen"; +}; + +&remoteproc_adsp_glink { + /delete-node/ apr; + + gpr { + compatible = "qcom,gpr"; + qcom,glink-channels = "adsp_apps"; + qcom,domain = ; + qcom,intents = <512 20>; + #address-cells = <1>; + #size-cells = <0>; + + q6apm: service@1 { + compatible = "qcom,q6apm"; + reg = ; + #sound-dai-cells = <0>; + qcom,protection-domain = "avs/audio", "msm/adsp/audio_pd"; + + q6apmdai: dais { + compatible = "qcom,q6apm-dais"; + iommus = <&apps_smmu 0x1801 0x0>; + }; + + q6apmbedai: bedais { + compatible = "qcom,q6apm-lpass-dais"; + #sound-dai-cells = <1>; + }; + }; + + q6prm: service@2 { + compatible = "qcom,q6prm"; + reg = ; + qcom,protection-domain = "avs/audio", "msm/adsp/audio_pd"; + + q6prmcc: clock-controller { + compatible = "qcom,q6prm-lpass-clocks"; + #clock-cells = <2>; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts index 5fbcd48f2e2d8..0da3525979c0b 100644 --- a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts +++ b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts @@ -19,6 +19,7 @@ #include "pm7325.dtsi" #include "pm8350c.dtsi" #include "pmk8350.dtsi" +#include "qcs6490-audioreach.dtsi" /delete-node/ &ipa_fw_mem; /delete-node/ &rmtfs_mem; @@ -765,6 +766,14 @@ }; }; +&lpass_va_macro { + status = "okay"; +}; + +&lpass_wsa_macro { + status = "okay"; +}; + &mdss { status = "okay"; }; @@ -966,6 +975,13 @@ status = "okay"; }; +&psci { + reset-types { + mode-bootloader = <0x10001 0x2>; + mode-edl = <0 0x1>; + }; +}; + &qup_uart7_cts { /* * Configure a bias-bus-hold on CTS to lower power @@ -1039,6 +1055,77 @@ status = "okay"; }; +&sound { + compatible = "qcom,qcs6490-rb3gen2-sndcard"; + model = "qcs6490-rb3gen2-snd-card"; + + audio-routing = "SpkrLeft IN", "WSA_SPK1 OUT", + "SpkrRight IN", "WSA_SPK2 OUT", + "VA DMIC0", "vdd-micb", + "VA DMIC1", "vdd-micb", + "VA DMIC2", "vdd-micb", + "VA DMIC3", "vdd-micb"; + + wsa-dai-link { + link-name = "WSA Playback"; + + codec { + sound-dai = <&left_spkr>, <&right_spkr>, + <&swr2 0>, <&lpass_wsa_macro 0>; + }; + + cpu { + sound-dai = <&q6apmbedai WSA_CODEC_DMA_RX_0>; + }; + + platform { + sound-dai = <&q6apm>; + }; + }; + + va-dai-link { + link-name = "VA Capture"; + + codec { + sound-dai = <&lpass_va_macro 0>; + }; + + cpu { + sound-dai = <&q6apmbedai VA_CODEC_DMA_TX_0>; + }; + + platform { + sound-dai = <&q6apm>; + }; + }; +}; + +&swr2 { + status = "okay"; + + left_spkr: speaker@0,1 { + compatible = "sdw10217020200"; + reg = <0 1>; + powerdown-gpios = <&tlmm 158 GPIO_ACTIVE_LOW>; + #sound-dai-cells = <0>; + sound-name-prefix = "SpkrLeft"; + #thermal-sensor-cells = <0>; + vdd-supply = <&vreg_l18b_1p8>; + qcom,port-mapping = <1 2 3 7>; + }; + + right_spkr: speaker@0,2 { + compatible = "sdw10217020200"; + reg = <0 2>; + powerdown-gpios = <&tlmm 158 GPIO_ACTIVE_LOW>; + #sound-dai-cells = <0>; + sound-name-prefix = "SpkrRight"; + #thermal-sensor-cells = <0>; + vdd-supply = <&vreg_l18b_1p8>; + qcom,port-mapping = <4 5 6 8>; + }; +}; + &tlmm { gpio-reserved-ranges = <32 2>, /* ADSP */ <48 4>; /* NFC */ diff --git a/arch/arm64/boot/dts/qcom/qcs9075-iq-9075-evk.dts b/arch/arm64/boot/dts/qcom/qcs9075-iq-9075-evk.dts new file mode 100644 index 0000000000000..ab161180d1d5a --- /dev/null +++ b/arch/arm64/boot/dts/qcom/qcs9075-iq-9075-evk.dts @@ -0,0 +1,290 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) 2024-2025, Qualcomm Innovation Center, Inc. All rights reserved. + */ +/dts-v1/; + +#include +#include + +#include "qcs9075.dtsi" +#include "sa8775p-pmics.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. IQ 9075 EVK"; + compatible = "qcom,qcs9075-iq-9075-evk", "qcom,qcs9075", "qcom,sa8775p"; + + aliases { + serial0 = &uart10; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; +}; + +&apps_rsc { + regulators-0 { + compatible = "qcom,pmm8654au-rpmh-regulators"; + qcom,pmic-id = "a"; + + vreg_s4a: smps4 { + regulator-name = "vreg_s4a"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1816000>; + regulator-initial-mode = ; + }; + + vreg_s5a: smps5 { + regulator-name = "vreg_s5a"; + regulator-min-microvolt = <1850000>; + regulator-max-microvolt = <1996000>; + regulator-initial-mode = ; + }; + + vreg_s9a: smps9 { + regulator-name = "vreg_s9a"; + regulator-min-microvolt = <535000>; + regulator-max-microvolt = <1120000>; + regulator-initial-mode = ; + }; + + vreg_l4a: ldo4 { + regulator-name = "vreg_l4a"; + regulator-min-microvolt = <788000>; + regulator-max-microvolt = <1050000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l5a: ldo5 { + regulator-name = "vreg_l5a"; + regulator-min-microvolt = <870000>; + regulator-max-microvolt = <950000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l6a: ldo6 { + regulator-name = "vreg_l6a"; + regulator-min-microvolt = <870000>; + regulator-max-microvolt = <970000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l7a: ldo7 { + regulator-name = "vreg_l7a"; + regulator-min-microvolt = <720000>; + regulator-max-microvolt = <950000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l8a: ldo8 { + regulator-name = "vreg_l8a"; + regulator-min-microvolt = <2504000>; + regulator-max-microvolt = <3300000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l9a: ldo9 { + regulator-name = "vreg_l9a"; + regulator-min-microvolt = <2970000>; + regulator-max-microvolt = <3544000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + }; + + regulators-1 { + compatible = "qcom,pmm8654au-rpmh-regulators"; + qcom,pmic-id = "c"; + + vreg_l1c: ldo1 { + regulator-name = "vreg_l1c"; + regulator-min-microvolt = <1140000>; + regulator-max-microvolt = <1260000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l2c: ldo2 { + regulator-name = "vreg_l2c"; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <1100000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l3c: ldo3 { + regulator-name = "vreg_l3c"; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1300000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l4c: ldo4 { + regulator-name = "vreg_l4c"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l5c: ldo5 { + regulator-name = "vreg_l5c"; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1300000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l6c: ldo6 { + regulator-name = "vreg_l6c"; + regulator-min-microvolt = <1620000>; + regulator-max-microvolt = <1980000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l7c: ldo7 { + regulator-name = "vreg_l7c"; + regulator-min-microvolt = <1620000>; + regulator-max-microvolt = <2000000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l8c: ldo8 { + regulator-name = "vreg_l8c"; + regulator-min-microvolt = <2400000>; + regulator-max-microvolt = <3300000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l9c: ldo9 { + regulator-name = "vreg_l9c"; + regulator-min-microvolt = <1650000>; + regulator-max-microvolt = <2700000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + }; + + regulators-2 { + compatible = "qcom,pmm8654au-rpmh-regulators"; + qcom,pmic-id = "e"; + + vreg_s4e: smps4 { + regulator-name = "vreg_s4e"; + regulator-min-microvolt = <970000>; + regulator-max-microvolt = <1520000>; + regulator-initial-mode = ; + }; + + vreg_s7e: smps7 { + regulator-name = "vreg_s7e"; + regulator-min-microvolt = <1010000>; + regulator-max-microvolt = <1170000>; + regulator-initial-mode = ; + }; + + vreg_s9e: smps9 { + regulator-name = "vreg_s9e"; + regulator-min-microvolt = <300000>; + regulator-max-microvolt = <570000>; + regulator-initial-mode = ; + }; + + vreg_l6e: ldo6 { + regulator-name = "vreg_l6e"; + regulator-min-microvolt = <1280000>; + regulator-max-microvolt = <1450000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + + vreg_l8e: ldo8 { + regulator-name = "vreg_l8e"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1950000>; + regulator-initial-mode = ; + regulator-allow-set-load; + regulator-allowed-modes = ; + }; + }; +}; + +&qupv3_id_1 { + status = "okay"; +}; + +&sleep_clk { + clock-frequency = <32768>; +}; + +&uart10 { + compatible = "qcom,geni-debug-uart"; + pinctrl-0 = <&qup_uart10_default>; + pinctrl-names = "default"; + + status = "okay"; +}; + +&ufs_mem_hc { + reset-gpios = <&tlmm 149 GPIO_ACTIVE_LOW>; + vcc-supply = <&vreg_l8a>; + vcc-max-microamp = <1100000>; + vccq-supply = <&vreg_l4c>; + vccq-max-microamp = <1200000>; + + status = "okay"; +}; + +&ufs_mem_phy { + vdda-phy-supply = <&vreg_l4a>; + vdda-pll-supply = <&vreg_l1c>; + + status = "okay"; +}; + +&xo_board_clk { + clock-frequency = <38400000>; +}; diff --git a/arch/arm64/boot/dts/qcom/qcs9075.dtsi b/arch/arm64/boot/dts/qcom/qcs9075.dtsi new file mode 100644 index 0000000000000..f3b1c5788367a --- /dev/null +++ b/arch/arm64/boot/dts/qcom/qcs9075.dtsi @@ -0,0 +1,116 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) 2025, Qualcomm Innovation Center, Inc. All rights reserved. + */ + +/dts-v1/; + +#include "sa8775p.dtsi" + +/delete-node/ &pil_camera_mem; +/delete-node/ &pil_adsp_mem; +/delete-node/ &pil_gdsp0_mem; +/delete-node/ &pil_gdsp1_mem; +/delete-node/ &pil_cdsp0_mem; +/delete-node/ &pil_gpu_mem; +/delete-node/ &pil_cdsp1_mem; +/delete-node/ &pil_cvp_mem; +/delete-node/ &pil_video_mem; +/delete-node/ &audio_mdf_mem; +/delete-node/ &trusted_apps_mem; +/delete-node/ &hyptz_reserved_mem; +/delete-node/ &tz_ffi_mem; + +/ { + reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + gunyah_md_mem: gunyah-md@91a80000 { + reg = <0x0 0x91a80000 0x0 0x80000>; + no-map; + }; + + pil_camera_mem: pil-camera@95200000 { + reg = <0x0 0x95200000 0x0 0x700000>; + no-map; + }; + + pil_adsp_mem: pil-adsp@95900000 { + reg = <0x0 0x95900000 0x0 0x1e00000>; + no-map; + }; + + q6_adsp_dtb_mem: q6-adsp-dtb@97700000 { + reg = <0x0 0x97700000 0x0 0x80000>; + no-map; + }; + + q6_gdsp0_dtb_mem: q6-gdsp0-dtb@97780000 { + reg = <0x0 0x97780000 0x0 0x80000>; + no-map; + }; + + pil_gdsp0_mem: pil-gdsp0@97800000 { + reg = <0x0 0x97800000 0x0 0x1e00000>; + no-map; + }; + + pil_gdsp1_mem: pil-gdsp1@99600000 { + reg = <0x0 0x99600000 0x0 0x1e00000>; + no-map; + }; + + q6_gdsp1_dtb_mem: q6-gdsp1-dtb@9b400000 { + reg = <0x0 0x9b400000 0x0 0x80000>; + no-map; + }; + + q6_cdsp0_dtb_mem: q6-cdsp0-dtb@9b480000 { + reg = <0x0 0x9b480000 0x0 0x80000>; + no-map; + }; + + pil_cdsp0_mem: pil-cdsp0@9b500000 { + reg = <0x0 0x9b500000 0x0 0x1e00000>; + no-map; + }; + + pil_gpu_mem: pil-gpu@9d300000 { + reg = <0x0 0x9d300000 0x0 0x2000>; + no-map; + }; + + q6_cdsp1_dtb_mem: q6-cdsp1-dtb@9d380000 { + reg = <0x0 0x9d380000 0x0 0x80000>; + no-map; + }; + + pil_cdsp1_mem: pil-cdsp1@9d400000 { + reg = <0x0 0x9d400000 0x0 0x1e00000>; + no-map; + }; + + pil_cvp_mem: pil-cvp@9f200000 { + reg = <0x0 0x9f200000 0x0 0x700000>; + no-map; + }; + + pil_video_mem: pil-video@9f900000 { + reg = <0x0 0x9f900000 0x0 0x1000000>; + no-map; + }; + + trusted_apps_mem: trusted-apps@d1900000 { + reg = <0x0 0xd1900000 0x0 0x1c00000>; + no-map; + }; + }; + + firmware { + scm { + /delete-property/ memory-region; + }; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/sa8775p-pmics.dtsi b/arch/arm64/boot/dts/qcom/sa8775p-pmics.dtsi index 1369c3d43f866..9e0d05c1b39ce 100644 --- a/arch/arm64/boot/dts/qcom/sa8775p-pmics.dtsi +++ b/arch/arm64/boot/dts/qcom/sa8775p-pmics.dtsi @@ -132,6 +132,13 @@ }; }; + pmm8654au_0_rtc: rtc@6100 { + compatible = "qcom,pmk8350-rtc"; + reg = <0x6100>, <0x6200>; + reg-names = "rtc", "alarm"; + interrupts = <0x0 0x62 0x1 IRQ_TYPE_EDGE_RISING>; + }; + pmm8654au_0_gpios: gpio@8800 { compatible = "qcom,pmm8654au-gpio", "qcom,spmi-gpio"; reg = <0x8800>; diff --git a/arch/arm64/boot/dts/qcom/sa8775p-ride.dtsi b/arch/arm64/boot/dts/qcom/sa8775p-ride.dtsi index 3ae416ab66e8b..aea13e45a1e23 100644 --- a/arch/arm64/boot/dts/qcom/sa8775p-ride.dtsi +++ b/arch/arm64/boot/dts/qcom/sa8775p-ride.dtsi @@ -651,6 +651,13 @@ "GNSS_BOOT_MODE"; }; +&psci { + reset-types { + mode-bootloader = <0x10001 0x2>; + mode-edl = <0 0x1>; + }; +}; + &qupv3_id_1 { status = "okay"; }; diff --git a/arch/arm64/boot/dts/qcom/sa8775p.dtsi b/arch/arm64/boot/dts/qcom/sa8775p.dtsi index 45f536633f644..889652303de51 100644 --- a/arch/arm64/boot/dts/qcom/sa8775p.dtsi +++ b/arch/arm64/boot/dts/qcom/sa8775p.dtsi @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -51,6 +52,11 @@ next-level-cache = <&l2_0>; capacity-dmips-mhz = <1024>; dynamic-power-coefficient = <100>; + operating-points-v2 = <&cpu0_opp_table>; + interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&epss_l3_cl0 MASTER_EPSS_L3_APPS + &epss_l3_cl0 SLAVE_EPSS_L3_SHARED>; l2_0: l2-cache { compatible = "cache"; cache-level = <2>; @@ -75,6 +81,11 @@ next-level-cache = <&l2_1>; capacity-dmips-mhz = <1024>; dynamic-power-coefficient = <100>; + operating-points-v2 = <&cpu0_opp_table>; + interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&epss_l3_cl0 MASTER_EPSS_L3_APPS + &epss_l3_cl0 SLAVE_EPSS_L3_SHARED>; l2_1: l2-cache { compatible = "cache"; cache-level = <2>; @@ -94,6 +105,11 @@ next-level-cache = <&l2_2>; capacity-dmips-mhz = <1024>; dynamic-power-coefficient = <100>; + operating-points-v2 = <&cpu0_opp_table>; + interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&epss_l3_cl0 MASTER_EPSS_L3_APPS + &epss_l3_cl0 SLAVE_EPSS_L3_SHARED>; l2_2: l2-cache { compatible = "cache"; cache-level = <2>; @@ -113,6 +129,11 @@ next-level-cache = <&l2_3>; capacity-dmips-mhz = <1024>; dynamic-power-coefficient = <100>; + operating-points-v2 = <&cpu0_opp_table>; + interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&epss_l3_cl0 MASTER_EPSS_L3_APPS + &epss_l3_cl0 SLAVE_EPSS_L3_SHARED>; l2_3: l2-cache { compatible = "cache"; cache-level = <2>; @@ -132,6 +153,11 @@ next-level-cache = <&l2_4>; capacity-dmips-mhz = <1024>; dynamic-power-coefficient = <100>; + operating-points-v2 = <&cpu4_opp_table>; + interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&epss_l3_cl1 MASTER_EPSS_L3_APPS + &epss_l3_cl1 SLAVE_EPSS_L3_SHARED>; l2_4: l2-cache { compatible = "cache"; cache-level = <2>; @@ -157,6 +183,11 @@ next-level-cache = <&l2_5>; capacity-dmips-mhz = <1024>; dynamic-power-coefficient = <100>; + operating-points-v2 = <&cpu4_opp_table>; + interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&epss_l3_cl1 MASTER_EPSS_L3_APPS + &epss_l3_cl1 SLAVE_EPSS_L3_SHARED>; l2_5: l2-cache { compatible = "cache"; cache-level = <2>; @@ -176,6 +207,11 @@ next-level-cache = <&l2_6>; capacity-dmips-mhz = <1024>; dynamic-power-coefficient = <100>; + operating-points-v2 = <&cpu4_opp_table>; + interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&epss_l3_cl1 MASTER_EPSS_L3_APPS + &epss_l3_cl1 SLAVE_EPSS_L3_SHARED>; l2_6: l2-cache { compatible = "cache"; cache-level = <2>; @@ -195,6 +231,11 @@ next-level-cache = <&l2_7>; capacity-dmips-mhz = <1024>; dynamic-power-coefficient = <100>; + operating-points-v2 = <&cpu4_opp_table>; + interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&epss_l3_cl1 MASTER_EPSS_L3_APPS + &epss_l3_cl1 SLAVE_EPSS_L3_SHARED>; l2_7: l2-cache { compatible = "cache"; cache-level = <2>; @@ -284,6 +325,176 @@ }; }; + cpu0_opp_table: opp-table-cpu0 { + compatible = "operating-points-v2"; + opp-shared; + + opp-1267200000 { + opp-hz = /bits/ 64 <1267200000>; + opp-peak-kBps = <(1555200 * 4) (921600 * 32)>; + }; + + opp-1363200000 { + opp-hz = /bits/ 64 <1363200000>; + opp-peak-kBps = <(1555200 * 4) (921600 * 32)>; + }; + + opp-1459200000 { + opp-hz = /bits/ 64 <1459200000>; + opp-peak-kBps = <(1555200 * 4) (921600 * 32)>; + }; + + opp-1536000000 { + opp-hz = /bits/ 64 <1536000000>; + opp-peak-kBps = <(1555200 * 4) (921600 * 32)>; + }; + + opp-1632000000 { + opp-hz = /bits/ 64 <1632000000>; + opp-peak-kBps = <(1708800 * 4) (1228800 * 32)>; + }; + + opp-1708800000 { + opp-hz = /bits/ 64 <1708800000>; + opp-peak-kBps = <(1708800 * 4) (1228800 * 32)>; + }; + + opp-1785600000 { + opp-hz = /bits/ 64 <1785600000>; + opp-peak-kBps = <(1708800 * 4) (1228800 * 32)>; + }; + + opp-1862400000 { + opp-hz = /bits/ 64 <1862400000>; + opp-peak-kBps = <(1708800 * 4) (1228800 * 32)>; + }; + + opp-1939200000 { + opp-hz = /bits/ 64 <1939200000>; + opp-peak-kBps = <(1708800 * 4) (1228800 * 32)>; + }; + + opp-2016000000 { + opp-hz = /bits/ 64 <2016000000>; + opp-peak-kBps = <(1708800 * 4) (1228800 * 32)>; + }; + + opp-2112000000 { + opp-hz = /bits/ 64 <2112000000>; + opp-peak-kBps = <(2092800 * 4) (1555200 * 32)>; + }; + + opp-2188800000 { + opp-hz = /bits/ 64 <2188800000>; + opp-peak-kBps = <(2092800 * 4) (1555200 * 32)>; + }; + + opp-2265600000 { + opp-hz = /bits/ 64 <2265600000>; + opp-peak-kBps = <(2092800 * 4) (1555200 * 32)>; + }; + + opp-2361600000 { + opp-hz = /bits/ 64 <2361600000>; + opp-peak-kBps = <(3196800 * 4) (1612800 * 32)>; + }; + + opp-2457600000 { + opp-hz = /bits/ 64 <2457600000>; + opp-peak-kBps = <(3196800 * 4) (1612800 * 32)>; + }; + + opp-2553600000 { + opp-hz = /bits/ 64 <2553600000>; + opp-peak-kBps = <(3196800 * 4) (1708800 * 32)>; + }; + }; + + cpu4_opp_table: opp-table-cpu4 { + compatible = "operating-points-v2"; + opp-shared; + + opp-1267200000 { + opp-hz = /bits/ 64 <1267200000>; + opp-peak-kBps = <(1555200 * 4) (921600 * 32)>; + }; + + opp-1363200000 { + opp-hz = /bits/ 64 <1363200000>; + opp-peak-kBps = <(1555200 * 4) (921600 * 32)>; + }; + + opp-1459200000 { + opp-hz = /bits/ 64 <1459200000>; + opp-peak-kBps = <(1555200 * 4) (921600 * 32)>; + }; + + opp-1536000000 { + opp-hz = /bits/ 64 <1536000000>; + opp-peak-kBps = <(1555200 * 4) (921600 * 32)>; + }; + + opp-1632000000 { + opp-hz = /bits/ 64 <1632000000>; + opp-peak-kBps = <(1708800 * 4) (1228800 * 32)>; + }; + + opp-1708800000 { + opp-hz = /bits/ 64 <1708800000>; + opp-peak-kBps = <(1708800 * 4) (1228800 * 32)>; + }; + + opp-1785600000 { + opp-hz = /bits/ 64 <1785600000>; + opp-peak-kBps = <(1708800 * 4) (1228800 * 32)>; + }; + + opp-1862400000 { + opp-hz = /bits/ 64 <1862400000>; + opp-peak-kBps = <(1708800 * 4) (1228800 * 32)>; + }; + + opp-1939200000 { + opp-hz = /bits/ 64 <1939200000>; + opp-peak-kBps = <(1708800 * 4) (1228800 * 32)>; + }; + + opp-2016000000 { + opp-hz = /bits/ 64 <2016000000>; + opp-peak-kBps = <(1708800 * 4) (1228800 * 32)>; + }; + + opp-2112000000 { + opp-hz = /bits/ 64 <2112000000>; + opp-peak-kBps = <(2092800 * 4) (1555200 * 32)>; + }; + + opp-2188800000 { + opp-hz = /bits/ 64 <2188800000>; + opp-peak-kBps = <(2092800 * 4) (1555200 * 32)>; + }; + + opp-2265600000 { + opp-hz = /bits/ 64 <2265600000>; + opp-peak-kBps = <(2092800 * 4) (1555200 * 32)>; + }; + + opp-2361600000 { + opp-hz = /bits/ 64 <2361600000>; + opp-peak-kBps = <(3196800 * 4) (1612800 * 32)>; + }; + + opp-2457600000 { + opp-hz = /bits/ 64 <2457600000>; + opp-peak-kBps = <(3196800 * 4) (1612800 * 32)>; + }; + + opp-2553600000 { + opp-hz = /bits/ 64 <2553600000>; + opp-peak-kBps = <(3196800 * 4) (1708800 * 32)>; + }; + }; + dummy-sink { compatible = "arm,coresight-dummy-sink"; @@ -409,7 +620,7 @@ interrupts = ; }; - psci { + psci: psci { compatible = "arm,psci-1.0"; method = "smc"; @@ -5548,6 +5759,15 @@ }; }; + epss_l3_cl0: interconnect@18590000 { + compatible = "qcom,sa8775p-epss-l3", + "qcom,epss-l3"; + reg = <0x0 0x18590000 0x0 0x1000>; + clocks = <&rpmhcc RPMH_CXO_CLK>, <&gcc GCC_GPLL0>; + clock-names = "xo", "alternate"; + #interconnect-cells = <1>; + }; + cpufreq_hw: cpufreq@18591000 { compatible = "qcom,sa8775p-cpufreq-epss", "qcom,cpufreq-epss"; @@ -5565,6 +5785,15 @@ #freq-domain-cells = <1>; }; + epss_l3_cl1: interconnect@18592000 { + compatible = "qcom,sa8775p-epss-l3", + "qcom,epss-l3"; + reg = <0x0 0x18592000 0x0 0x1000>; + clocks = <&rpmhcc RPMH_CXO_CLK>, <&gcc GCC_GPLL0>; + clock-names = "xo", "alternate"; + #interconnect-cells = <1>; + }; + remoteproc_gpdsp0: remoteproc@20c00000 { compatible = "qcom,sa8775p-gpdsp0-pas"; reg = <0x0 0x20c00000 0x0 0x10000>; diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi b/arch/arm64/boot/dts/qcom/sc7280.dtsi index b1cc3bc1aec8b..685e9cd27d8f7 100644 --- a/arch/arm64/boot/dts/qcom/sc7280.dtsi +++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi @@ -857,7 +857,7 @@ interrupts = ; }; - psci { + psci: psci { compatible = "arm,psci-1.0"; method = "smc"; @@ -2636,6 +2636,66 @@ status = "disabled"; }; + lpass_wsa_macro: codec@3240000 { + compatible = "qcom,sc7280-lpass-wsa-macro"; + reg = <0x0 0x03240000 0x0 0x1000>; + + clocks = <&lpass_aon LPASS_AON_CC_TX_MCLK_CLK>, + <&lpass_aon LPASS_AON_CC_TX_MCLK_2X_CLK>, + <&lpass_va_macro>; + clock-names = "mclk", + "npl", + "fsgen"; + + pinctrl-0 = <&lpass_wsa_swr_clk>, <&lpass_wsa_swr_data>; + pinctrl-names = "default"; + + power-domains = <&lpass_hm LPASS_CORE_CC_LPASS_CORE_HM_GDSC>, + <&lpass_aon LPASS_AON_CC_LPASS_AUDIO_HM_GDSC>; + power-domain-names = "macro", "dcodec"; + + #clock-cells = <0>; + clock-output-names = "mclk"; + #sound-dai-cells = <1>; + + status = "disabled"; + }; + + swr2: soundwire@3250000 { + compatible = "qcom,soundwire-v1.6.0"; + reg = <0x0 0x03250000 0x0 0x2000>; + + interrupts = ; + clocks = <&lpass_wsa_macro>; + clock-names = "iface"; + + resets = <&lpass_audiocc LPASS_AUDIO_SWR_WSA_CGCR>; + reset-names = "swr_audio_cgcr"; + + qcom,din-ports = <2>; + qcom,dout-ports = <6>; + + qcom,ports-sinterval-low = /bits/ 8 <0x07 0x1f 0x3f 0x07 + 0x1f 0x3f 0x0f 0x0f>; + qcom,ports-offset1 = /bits/ 8 <0x01 0x02 0x0c 0x06 0x12 0x0d 0x07 0x0a>; + qcom,ports-offset2 = /bits/ 8 <0xff 0x00 0x1f 0xff 0x00 0x1f 0x00 0x00>; + qcom,ports-hstart = /bits/ 8 <0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff>; + qcom,ports-hstop = /bits/ 8 <0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff>; + qcom,ports-word-length = /bits/ 8 <0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff>; + qcom,ports-block-pack-mode = /bits/ 8 <0xff 0xff 0x01 0xff 0xff 0x01 + 0xff 0xff>; + qcom,ports-block-group-count = /bits/ 8 <0xff 0xff 0xff 0xff 0xff 0xff + 0xff 0xff>; + qcom,ports-lane-control = /bits/ 8 <0xff 0xff 0xff 0xff 0xff 0xff + 0xff 0xff>; + + #address-cells = <2>; + #size-cells = <0>; + #sound-dai-cells = <1>; + + status = "disabled"; + }; + lpass_audiocc: clock-controller@3300000 { compatible = "qcom,sc7280-lpassaudiocc"; reg = <0 0x03300000 0 0x30000>, @@ -2839,6 +2899,22 @@ pins = "gpio1", "gpio2", "gpio14"; function = "swr_tx_data"; }; + + lpass_wsa_swr_clk: wsa-swr-clk-state { + pins = "gpio10"; + function = "wsa_swr_clk"; + drive-strength = <2>; + slew-rate = <1>; + bias-disable; + }; + + lpass_wsa_swr_data: wsa-swr-data-state { + pins = "gpio11"; + function = "wsa_swr_data"; + drive-strength = <2>; + slew-rate = <1>; + bias-bus-hold; + }; }; gpu: gpu@3d00000 { @@ -3814,7 +3890,7 @@ status = "disabled"; - glink-edge { + remoteproc_adsp_glink: glink-edge { interrupts-extended = <&ipcc IPCC_CLIENT_LPASS IPCC_MPROC_SIGNAL_GLINK_QMP IRQ_TYPE_EDGE_RISING>; diff --git a/arch/arm64/configs/prune.config b/arch/arm64/configs/prune.config new file mode 100644 index 0000000000000..01bb1243552ea --- /dev/null +++ b/arch/arm64/configs/prune.config @@ -0,0 +1,410 @@ +# CONFIG_ARCH_ACTIONS is not set +# CONFIG_ARCH_AIROHA is not set +# CONFIG_ARCH_SUNXI is not set +# CONFIG_ARCH_ALPINE is not set +# CONFIG_ARCH_APPLE is not set +# CONFIG_ARCH_BCM is not set +# CONFIG_ARCH_BCM2835 is not set +# CONFIG_ARCH_BCM_IPROC is not set +# CONFIG_ARCH_BCMBCA is not set +# CONFIG_ARCH_BRCMSTB is not set +# CONFIG_ARCH_BERLIN is not set +# CONFIG_ARCH_BLAIZE is not set +# CONFIG_ARCH_EXYNOS is not set +# CONFIG_ARCH_SPARX5 is not set +# CONFIG_ARCH_K3 is not set +# CONFIG_ARCH_LG1K is not set +# CONFIG_ARCH_HISI is not set +# CONFIG_ARCH_KEEMBAY is not set +# CONFIG_ARCH_MEDIATEK is not set +# CONFIG_ARCH_MESON is not set +# CONFIG_ARCH_MVEBU is not set +# CONFIG_ARCH_NXP is not set +# CONFIG_ARCH_MA35 is not set +# CONFIG_ARCH_NPCM is not set +# CONFIG_ARCH_REALTEK is not set +# CONFIG_ARCH_RENESAS is not set +# CONFIG_ARCH_ROCKCHIP is not set +# CONFIG_ARCH_SEATTLE is not set +# CONFIG_ARCH_INTEL_SOCFPGA is not set +# CONFIG_ARCH_STM32 is not set +# CONFIG_ARCH_SYNQUACER is not set +# CONFIG_ARCH_TEGRA is not set +# CONFIG_ARCH_TESLA_FSD is not set +# CONFIG_ARCH_SPRD is not set +# CONFIG_ARCH_THUNDER is not set +# CONFIG_ARCH_THUNDER2 is not set +# CONFIG_ARCH_UNIPHIER is not set +# CONFIG_ARCH_VEXPRESS is not set +# CONFIG_ARCH_VISCONTI is not set +# CONFIG_ARCH_XGENE is not set +# CONFIG_ARCH_ZYNQMP is not set +# CONFIG_MOUSE_PS2 is not set +# CONFIG_KEYBOARD_ATKBD is not set +# CONFIG_VSOCKETS_DIAG is not set +# CONFIG_VSOCKETS_LOOPBACK is not set +# CONFIG_RODATA_FULL_DEFAULT_ENABLED is not set +# CONFIG_NET_DSA_TAG_OCELOT is not set +# CONFIG_NET_DSA_TAG_OCELOT_8021Q is not set +# CONFIG_BT_HCIBTUSB_MTK is not set +# CONFIG_BT_HCIUART_BCM is not set +# CONFIG_BT_HCIUART_MRVL is not set +# CONFIG_BT_MRVL is not set +# CONFIG_BT_MRVL_SDIO is not set +# CONFIG_PCIE_ALTERA is not set +# CONFIG_PCIE_ALTERA_MSI is not set +# CONFIG_PCI_HOST_THUNDER_PEM is not set +# CONFIG_PCI_HOST_THUNDER_ECAM is not set +# CONFIG_PCI_XGENE is not set +# CONFIG_PCI_MESON is not set +# CONFIG_PCI_HISI is not set +# CONFIG_PCIE_KIRIN is not set +# CONFIG_BRCMSTB_GISB_ARB is not set +# CONFIG_VEXPRESS_CONFIG is not set +# CONFIG_GNSS_MTK_SERIAL is not set +# CONFIG_MTD_CFI_INTELEXT is not set +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +# CONFIG_MTD_NAND_DENALI_DT is not set +# CONFIG_MTD_NAND_BRCMNAND is not set +# CONFIG_MTD_NAND_BRCMNAND_BCMBCA is not set +# CONFIG_MTD_NAND_BRCMNAND_BRCMSTB is not set +# CONFIG_MTD_NAND_BRCMNAND_IPROC is not set +# CONFIG_B53_SRAB_DRIVER is not set +# CONFIG_NET_DSA_BCM_SF2 is not set +# CONFIG_AMD_XGBE is not set +# CONFIG_BCMGENET is not set +# CONFIG_BNX2X is not set +# CONFIG_SYSTEMPORT is not set +# CONFIG_MACB is not set +# CONFIG_THUNDER_NIC_PF is not set +# CONFIG_HIX5HD2_GMAC is not set +# CONFIG_HNS_DSAF is not set +# CONFIG_HNS_ENET is not set +# CONFIG_HNS3 is not set +# CONFIG_HNS3_HCLGE is not set +# CONFIG_HNS3_ENET is not set +# CONFIG_E1000 is not set +# CONFIG_E1000E is not set +# CONFIG_IGB is not set +# CONFIG_IGBVF is not set +# CONFIG_MVMDIO is not set +# CONFIG_SKY2 is not set +# CONFIG_MLX4_EN is not set +# CONFIG_MLX5_CORE is not set +# CONFIG_MLX5_CORE_EN is not set +# CONFIG_R8169 is not set +# CONFIG_SMC91X is not set +# CONFIG_SMSC911X is not set +# CONFIG_BROADCOM_PHY is not set +# CONFIG_BCM54140_PHY is not set +# CONFIG_MARVELL_PHY is not set +# CONFIG_MARVELL_10G_PHY is not set +# CONFIG_MICROSEMI_PHY is not set +# CONFIG_REALTEK_PHY is not set +# CONFIG_ROCKCHIP_PHY is not set +# CONFIG_DP83867_PHY is not set +# CONFIG_DP83TD510_PHY is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_CAN_FLEXCAN is not set +# CONFIG_CAN_MCP251XFD is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_RTL8152 is not set +# CONFIG_USB_LAN78XX is not set +# CONFIG_USB_NET_DM9601 is not set +# CONFIG_USB_NET_SR9800 is not set +# CONFIG_USB_NET_SMSC75XX is not set +# CONFIG_USB_NET_SMSC95XX is not set +# CONFIG_USB_NET_PLUSB is not set +# CONFIG_USB_NET_MCS7830 is not set +# CONFIG_BRCMFMAC is not set +# CONFIG_MWIFIEX is not set +# CONFIG_MWIFIEX_SDIO is not set +# CONFIG_MWIFIEX_PCIE is not set +# CONFIG_MT7921E is not set +# CONFIG_WL18XX is not set +# CONFIG_WLCORE_SDIO is not set +# CONFIG_KEYBOARD_CROS_EC is not set +# CONFIG_KEYBOARD_MTK_PMIC is not set +# CONFIG_MOUSE_ELAN_I2C is not set +# CONFIG_TOUCHSCREEN_ATMEL_MXT is not set +# CONFIG_TOUCHSCREEN_GOODIX is not set +# CONFIG_TOUCHSCREEN_ELAN is not set +# CONFIG_TOUCHSCREEN_EDT_FT5X06 is not set +# CONFIG_INPUT_TPS65219_PWRBUTTON is not set +# CONFIG_SERIAL_XILINX_PS_UART is not set +# CONFIG_SERIAL_XILINX_PS_UART_CONSOLE is not set +# CONFIG_SERIAL_FSL_LPUART is not set +# CONFIG_SERIAL_FSL_LPUART_CONSOLE is not set +# CONFIG_SERIAL_FSL_LINFLEXUART is not set +# CONFIG_SERIAL_FSL_LINFLEXUART_CONSOLE is not set +# CONFIG_TCG_TIS_SPI_CR50 is not set +# CONFIG_TCG_TIS_I2C_CR50 is not set +# CONFIG_TCG_TIS_I2C_INFINEON is not set +# CONFIG_I2C_CADENCE is not set +# CONFIG_I2C_DESIGNWARE_PLATFORM is not set +# CONFIG_I2C_RK3X is not set +# CONFIG_I2C_CROS_EC_TUNNEL is not set +# CONFIG_SPI_CADENCE_QUADSPI is not set +# CONFIG_SPI_DESIGNWARE is not set +# CONFIG_SPI_DW_DMA is not set +# CONFIG_SPI_DW_MMIO is not set +# CONFIG_PINCTRL_MAX77620 is not set +# CONFIG_GPIO_ALTERA is not set +# CONFIG_GPIO_DWAPB is not set +# CONFIG_GPIO_MB86S7X is not set +# CONFIG_GPIO_XGENE is not set +# CONFIG_GPIO_MAX732X is not set +# CONFIG_GPIO_PCA953X is not set +# CONFIG_GPIO_PCA953X_IRQ is not set +# CONFIG_GPIO_BD9571MWV is not set +# CONFIG_GPIO_MAX77620 is not set +# CONFIG_POWER_RESET_BRCMSTB is not set +# CONFIG_POWER_RESET_XGENE is not set +# CONFIG_BATTERY_SBS is not set +# CONFIG_BATTERY_BQ27XXX is not set +# CONFIG_BATTERY_MAX17042 is not set +# CONFIG_CHARGER_MT6360 is not set +# CONFIG_CHARGER_BQ25890 is not set +# CONFIG_CHARGER_BQ25980 is not set +# CONFIG_SENSORS_JC42 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_INA2XX is not set +# CONFIG_SENSORS_INA3221 is not set +# CONFIG_ARM_SP805_WATCHDOG is not set +# CONFIG_DW_WATCHDOG is not set +# CONFIG_ARM_SMC_WATCHDOG is not set +# CONFIG_PM8916_WATCHDOG is not set +# CONFIG_MFD_BD9571MWV is not set +# CONFIG_MFD_AXP20X_I2C is not set +# CONFIG_MFD_HI6421_PMIC is not set +# CONFIG_MFD_MAX77620 is not set +# CONFIG_MFD_MT6360 is not set +# CONFIG_MFD_MT6397 is not set +# CONFIG_MFD_RK8XX_I2C is not set +# CONFIG_MFD_RK8XX_SPI is not set +# CONFIG_MFD_SEC_CORE is not set +# CONFIG_MFD_TI_AM335X_TSCADC is not set +# CONFIG_MFD_TPS65219 is not set +# CONFIG_MFD_WM8994 is not set +# CONFIG_MFD_ROHM_BD718XX is not set +# CONFIG_REGULATOR_AXP20X is not set +# CONFIG_REGULATOR_BD718XX is not set +# CONFIG_REGULATOR_BD9571MWV is not set +# CONFIG_REGULATOR_CROS_EC is not set +# CONFIG_REGULATOR_FAN53555 is not set +# CONFIG_REGULATOR_HI6421V530 is not set +# CONFIG_REGULATOR_MAX77620 is not set +# CONFIG_REGULATOR_MAX8973 is not set +# CONFIG_REGULATOR_MP8859 is not set +# CONFIG_REGULATOR_MT6315 is not set +# CONFIG_REGULATOR_MT6357 is not set +# CONFIG_REGULATOR_MT6358 is not set +# CONFIG_REGULATOR_MT6359 is not set +# CONFIG_REGULATOR_MT6360 is not set +# CONFIG_REGULATOR_MT6397 is not set +# CONFIG_REGULATOR_PCA9450 is not set +# CONFIG_REGULATOR_PF8X00 is not set +# CONFIG_REGULATOR_PFUZE100 is not set +# CONFIG_REGULATOR_RK808 is not set +# CONFIG_REGULATOR_S2MPS11 is not set +# CONFIG_REGULATOR_TPS65132 is not set +# CONFIG_REGULATOR_TPS65219 is not set +# CONFIG_REGULATOR_RK808 is not set +# CONFIG_REGULATOR_S2MPS11 is not set +# CONFIG_REGULATOR_TPS65132 is not set +# CONFIG_REGULATOR_TPS65219 is not set +# CONFIG_MEDIA_ANALOG_TV_SUPPORT is not set +# CONFIG_MEDIA_DIGITAL_TV_SUPPORT is not set +# CONFIG_VIDEO_IMX219 is not set +# CONFIG_VIDEO_IMX412 is not set +# CONFIG_VIDEO_OV5640 is not set +# CONFIG_VIDEO_OV5645 is not set +# CONFIG_DRM_I2C_NXP_TDA998X is not set +# CONFIG_DRM_MALI_DISPLAY is not set +# CONFIG_DRM_KOMEDA is not set +# CONFIG_DRM_NOUVEAU is not set +# CONFIG_DRM_PANEL_BOE_TV101WUM_NL6 is not set +# CONFIG_DRM_PANEL_MANTIX_MLAF057WE51 is not set +# CONFIG_DRM_PANEL_RAYDIUM_RM67191 is not set +# CONFIG_DRM_PANEL_SITRONIX_ST7703 is not set +# CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA is not set +# CONFIG_DRM_PANEL_VISIONOX_VTDR6130 is not set +# CONFIG_DRM_LONTIUM_LT8912B is not set +# CONFIG_DRM_NWL_MIPI_DSI is not set +# CONFIG_DRM_PARADE_PS8640 is not set +# CONFIG_DRM_SAMSUNG_DSIM is not set +# CONFIG_DRM_SII902X is not set +# CONFIG_DRM_SIMPLE_BRIDGE is not set +# CONFIG_DRM_THINE_THC63LVD1024 is not set +# CONFIG_DRM_TOSHIBA_TC358768 is not set +# CONFIG_DRM_TI_TFP410 is not set +# CONFIG_DRM_TI_SN65DSI83 is not set +# CONFIG_DRM_TI_SN65DSI86 is not set +# CONFIG_DRM_I2C_ADV7511_AUDIO is not set +# CONFIG_DRM_CDNS_MHDP8546 is not set +# CONFIG_DRM_ETNAVIV is not set +# CONFIG_DRM_HISI_HIBMC is not set +# CONFIG_DRM_HISI_KIRIN is not set +# CONFIG_DRM_PL111 is not set +# CONFIG_DRM_LIMA is not set +# CONFIG_DRM_PANFROST is not set +# CONFIG_DRM_TIDSS is not set +# CONFIG_BACKLIGHT_LP855X is not set +# CONFIG_SND_SOC_FSL_ASRC is not set +# CONFIG_SND_SOC_FSL_SAI is not set +# CONFIG_SND_SOC_FSL_AUDMIX is not set +# CONFIG_SND_SOC_FSL_SSI is not set +# CONFIG_SND_SOC_FSL_SPDIF is not set +# CONFIG_SND_SOC_FSL_ESAI is not set +# CONFIG_SND_SOC_FSL_MICFIL is not set +# CONFIG_SND_SOC_FSL_EASRC is not set +# CONFIG_SND_SOC_IMX_AUDMUX is not set +# CONFIG_SND_SOC_AK4613 is not set +# CONFIG_SND_SOC_BT_SCO is not set +# CONFIG_SND_SOC_DA7213 is not set +# CONFIG_SND_SOC_DMIC is not set +# CONFIG_SND_SOC_ES7134 is not set +# CONFIG_SND_SOC_ES7241 is not set +# CONFIG_SND_SOC_ES8316 is not set +# CONFIG_SND_SOC_GTM601 is not set +# CONFIG_SND_SOC_PCM3168A_I2C is not set +# CONFIG_SND_SOC_RT5640 is not set +# CONFIG_SND_SOC_RT5659 is not set +# CONFIG_SND_SOC_SGTL5000 is not set +# CONFIG_SND_SOC_SIMPLE_AMPLIFIER is not set +# CONFIG_SND_SOC_SIMPLE_MUX is not set +# CONFIG_SND_SOC_SPDIF is not set +# CONFIG_SND_SOC_TAS2552 is not set +# CONFIG_SND_SOC_TAS571X is not set +# CONFIG_SND_SOC_TLV320AIC31XX is not set +# CONFIG_SND_SOC_TLV320AIC32X4_I2C is not set +# CONFIG_SND_SOC_TLV320AIC3X_I2C is not set +# CONFIG_SND_SOC_TS3A227E is not set +# CONFIG_SND_SOC_WM8524 is not set +# CONFIG_SND_SOC_WM8904 is not set +# CONFIG_SND_SOC_WM8960 is not set +# CONFIG_SND_SOC_WM8962 is not set +# CONFIG_SND_SOC_WM8978 is not set +# CONFIG_SND_SOC_MT6358 is not set +# CONFIG_SND_SOC_NAU8822 is not set +# CONFIG_USB_CDNS_SUPPORT is not set +# CONFIG_USB_CDNS3 is not set +# CONFIG_USB_CDNS3_GADGET is not set +# CONFIG_USB_CDNS3_HOST is not set +# CONFIG_USB_MUSB_HDRC is not set +# CONFIG_USB_CHIPIDEA is not set +# CONFIG_USB_CHIPIDEA_UDC is not set +# CONFIG_USB_CHIPIDEA_HOST is not set +# CONFIG_USB_ISP1760 is not set +# CONFIG_USB_SERIAL_CP210X is not set +# CONFIG_USB_HSIC_USB3503 is not set +# CONFIG_USB_SNP_UDC_PLAT is not set +# CONFIG_USB_BDC_UDC is not set +# CONFIG_TYPEC_FUSB302 is not set +# CONFIG_UCSI_CCG is not set +# CONFIG_TYPEC_TPS6598X is not set +# CONFIG_MMC_SDHCI_OF_ARASAN is not set +# CONFIG_MMC_SDHCI_OF_DWCMSHC is not set +# CONFIG_MMC_SDHCI_CADENCE is not set +# CONFIG_MMC_SDHCI_F_SDH30 is not set +# CONFIG_MMC_DW is not set +# CONFIG_MMC_DW_EXYNOS is not set +# CONFIG_MMC_DW_HI3798CV200 is not set +# CONFIG_MMC_DW_K3 is not set +# CONFIG_MMC_MTK is not set +# CONFIG_MMC_SDHCI_XENON is not set +# CONFIG_MMC_SDHCI_AM654 is not set +# CONFIG_LEDS_LM3692X is not set +# CONFIG_LEDS_PCA9532 is not set +# CONFIG_RTC_DRV_DS1307 is not set +# CONFIG_RTC_DRV_HYM8563 is not set +# CONFIG_RTC_DRV_MAX77686 is not set +# CONFIG_RTC_DRV_RK808 is not set +# CONFIG_RTC_DRV_PCF85063 is not set +# CONFIG_RTC_DRV_PCF85363 is not set +# CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_BQ32K is not set +# CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_RV3028 is not set +# CONFIG_RTC_DRV_RV8803 is not set +# CONFIG_RTC_DRV_S5M is not set +# CONFIG_RTC_DRV_DS3232 is not set +# CONFIG_RTC_DRV_PCF2127 is not set +# CONFIG_RTC_DRV_CROS_EC is not set +# CONFIG_RTC_DRV_MT6397 is not set +# CONFIG_BCM_SBA_RAID is not set +# CONFIG_FSL_EDMA is not set +# CONFIG_MV_XOR_V2 is not set +# CONFIG_VIDEO_MAX96712 is not set +# CONFIG_CHROME_PLATFORMS is not set +# CONFIG_CROS_EC is not set +# CONFIG_CROS_EC_I2C is not set +# CONFIG_CROS_EC_RPMSG is not set +# CONFIG_CROS_EC_SPI is not set +# CONFIG_CROS_EC_CHARDEV is not set +# CONFIG_CLK_VEXPRESS_OSC is not set +# CONFIG_COMMON_CLK_RK808 is not set +# CONFIG_COMMON_CLK_CS2000_CP is not set +# CONFIG_COMMON_CLK_S2MPS11 is not set +# CONFIG_COMMON_CLK_XGENE is not set +# CONFIG_COMMON_CLK_RS9_PCIE is not set +# CONFIG_COMMON_CLK_VC5 is not set +# CONFIG_COMMON_CLK_BD718XX is not set +# CONFIG_SOC_TI is not set +# CONFIG_EXTCON_PTN5150 is not set +# CONFIG_EXTCON_USBC_CROS_EC is not set +# CONFIG_MAX9611 is not set +# CONFIG_TI_ADS1015 is not set +# CONFIG_TI_AM335X_ADC is not set +# CONFIG_IIO_CROS_EC_SENSORS_CORE is not set +# CONFIG_IIO_CROS_EC_SENSORS is not set +# CONFIG_IIO_ST_LSM6DSX is not set +# CONFIG_IIO_CROS_EC_LIGHT_PROX is not set +# CONFIG_SENSORS_ISL29018 is not set +# CONFIG_VCNL4000 is not set +# CONFIG_IIO_ST_MAGN_3AXIS is not set +# CONFIG_IIO_CROS_EC_BARO is not set +# CONFIG_MPL3115 is not set +# CONFIG_PWM_CROS_EC is not set +# CONFIG_PHY_CADENCE_TORRENT is not set +# CONFIG_PHY_CADENCE_SIERRA is not set +# CONFIG_CRYPTO_CRCT10DIF_ARM64_CE is not set +# CONFIG_CRYPTO_DEV_HISI_SEC2 is not set +# CONFIG_CRYPTO_DEV_HISI_ZIP is not set +# CONFIG_CRYPTO_DEV_HISI_HPRE is not set +# CONFIG_CRYPTO_DEV_HISI_TRNG is not set +# CONFIG_CRYPTO_DEV_AMLOGIC_GXL is not set +# CONFIG_WATCHDOG_PRETIMEOUT_DEFAULT_GOV_NOOP is not set +# CONFIG_DEVMEM is not set +# CONFIG_STRICT_DEVMEM is not set +# CONFIG_SECURITY_SELINUX_BOOTPARAM is not set +# CONFIG_SECURITY_SELINUX_DEVELOP is not set +# CONFIG_SECURITY_SELINUX_AVC_STATS is not set +# CONFIG_AUDIT_GENERIC is not set +# CONFIG_EFI_DISABLE_RUNTIME is not set +# CONFIG_ACORN_PARTITION is not set +# CONFIG_AIX_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_CMDLINE_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_SYSV68_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_VFIO_PLATFORM_CALXEDAXGMAC_RESET is not set +# CONFIG_VFIO_PLATFORM_AMDXGBE_RESET is not set +# CONFIG_VFIO_PLATFORM_BCMFLEXRM_RESET is not set +# CONFIG_FTRACE_RECORD_RECURSION is not set +# CONFIG_FTRACE_STARTUP_TEST is not set +# CONFIG_FUNCTION_GRAPH_RETVAL is not set +# CONFIG_FUNCTION_PROFILER is not set +# CONFIG_HID_BPF is not set +# CONFIG_KPROBE_EVENTS_ON_NOTRACE is not set +# CONFIG_PSTORE_FTRACE is not set diff --git a/drivers/firmware/psci/psci.c b/drivers/firmware/psci/psci.c index 38ca190d4a22d..cbe28182dd644 100644 --- a/drivers/firmware/psci/psci.c +++ b/drivers/firmware/psci/psci.c @@ -80,6 +80,14 @@ static u32 psci_cpu_suspend_feature; static bool psci_system_reset2_supported; static bool psci_system_off2_hibernate_supported; +struct psci_reset_param { + const char *mode; + u32 reset_type; + u32 cookie; +}; +static struct psci_reset_param *psci_reset_params __ro_after_init; +static size_t num_psci_reset_params __ro_after_init; + static inline bool psci_has_ext_power_state(void) { return psci_cpu_suspend_feature & @@ -306,9 +314,39 @@ static int get_set_conduit_method(const struct device_node *np) return 0; } +static int psci_vendor_system_reset2(const char *cmd) +{ + unsigned long ret; + size_t i; + + for (i = 0; i < num_psci_reset_params; i++) { + if (!strcmp(psci_reset_params[i].mode, cmd)) { + ret = invoke_psci_fn(PSCI_FN_NATIVE(1_1, SYSTEM_RESET2), + psci_reset_params[i].reset_type, + psci_reset_params[i].cookie, 0); + /* + * if vendor reset fails, log it and fall back to + * architecture reset types + */ + pr_err("failed to perform reset \"%s\": %ld\n", cmd, + (long)ret); + return 0; + } + } + + return -ENOENT; +} + static int psci_sys_reset(struct notifier_block *nb, unsigned long action, void *data) { + /* + * try to do the vendor system_reset2 + * If there wasn't a matching command, fall back to architectural resets + */ + if (data && !psci_vendor_system_reset2(data)) + return NOTIFY_DONE; + if ((reboot_mode == REBOOT_WARM || reboot_mode == REBOOT_SOFT) && psci_system_reset2_supported) { /* @@ -795,6 +833,73 @@ static const struct of_device_id psci_of_match[] __initconst = { {}, }; +#define REBOOT_PREFIX "mode-" + +static int __init psci_init_system_reset2_modes(void) +{ + const size_t len = strlen(REBOOT_PREFIX); + struct psci_reset_param *param; + struct device_node *psci_np __free(device_node) = NULL; + struct device_node *np __free(device_node) = NULL; + struct property *prop; + size_t count = 0; + u32 magic[2]; + int num; + + if (!psci_system_reset2_supported) + return 0; + + psci_np = of_find_matching_node(NULL, psci_of_match); + if (!psci_np) + return 0; + + np = of_find_node_by_name(psci_np, "reset-types"); + if (!np) + return 0; + + for_each_property_of_node(np, prop) { + if (strncmp(prop->name, REBOOT_PREFIX, len)) + continue; + num = of_property_count_u32_elems(np, prop->name); + if (num != 1 && num != 2) + continue; + + count++; + } + + param = psci_reset_params = + kcalloc(count, sizeof(*psci_reset_params), GFP_KERNEL); + if (!psci_reset_params) + return -ENOMEM; + + for_each_property_of_node(np, prop) { + if (strncmp(prop->name, REBOOT_PREFIX, len)) + continue; + + num = of_property_read_variable_u32_array(np, prop->name, magic, + 1, ARRAY_SIZE(magic)); + if (num < 0) { + pr_warn("Failed to parse vendor reboot mode %s\n", + param->mode); + kfree_const(param->mode); + continue; + } + + param->mode = kstrdup_const(prop->name + len, GFP_KERNEL); + if (!param->mode) + continue; + + /* Force reset type to be in vendor space */ + param->reset_type = PSCI_1_1_RESET_TYPE_VENDOR_START | magic[0]; + param->cookie = num > 1 ? magic[1] : 0; + param++; + num_psci_reset_params++; + } + + return 0; +} +arch_initcall(psci_init_system_reset2_modes); + int __init psci_dt_init(void) { struct device_node *np; diff --git a/drivers/hwtracing/coresight/Kconfig b/drivers/hwtracing/coresight/Kconfig index f064e3d172b3d..02ef739f5fef7 100644 --- a/drivers/hwtracing/coresight/Kconfig +++ b/drivers/hwtracing/coresight/Kconfig @@ -268,4 +268,38 @@ config CORESIGHT_KUNIT_TESTS Enable Coresight unit tests. Only useful for development and not intended for production. +config CORESIGHT_QMI + tristate "CORESIGHT QMI support" + select QCOM_QMI_HELPERS + help + Enables support for sending command to subsystem via QMI. This is + primarily used for sending QMI message to subsystems for remote trace + sources. + + To compile this driver as a module, choose M here: the module will be + called coresight-qmi. + +config CORESIGHT_REMOTE_ETM + tristate "Remote processor ETM trace support" + depends on QCOM_QMI_HELPERS + help + Enables support for ETM trace collection on remote processor using + CoreSight framework. Enabling this will allow turning on ETM + tracing on remote processor via sysfs by configuring the required + CoreSight components. + + To compile this driver as a module, choose M here: the module will be + called coresight-remote-etm. + +config CORESIGHT_TGU + tristate "CoreSight Trigger Generation Unit driver" + help + This driver provides support for Trigger Generation Unit that is + used to detect patterns or sequences on a given set of signals. + TGU is used to monitor a particular bus within a given region to + detect illegal transaction sequences or slave responses. It is also + used to monitor a data stream to detect protocol violations and to + provide a trigger point for centering data around a specific event + within the trace data buffer. + endif diff --git a/drivers/hwtracing/coresight/Makefile b/drivers/hwtracing/coresight/Makefile index 4e7cc3c5bf994..e2e5c309e9a9b 100644 --- a/drivers/hwtracing/coresight/Makefile +++ b/drivers/hwtracing/coresight/Makefile @@ -52,7 +52,10 @@ obj-$(CONFIG_CORESIGHT_TPDA) += coresight-tpda.o coresight-cti-y := coresight-cti-core.o coresight-cti-platform.o \ coresight-cti-sysfs.o obj-$(CONFIG_ULTRASOC_SMB) += ultrasoc-smb.o +obj-$(CONFIG_CORESIGHT_QMI) += coresight-qmi.o +obj-$(CONFIG_CORESIGHT_REMOTE_ETM) += coresight-remote-etm.o obj-$(CONFIG_CORESIGHT_DUMMY) += coresight-dummy.o +obj-$(CONFIG_CORESIGHT_TGU) += coresight-tgu.o obj-$(CONFIG_CORESIGHT_CTCU) += coresight-ctcu.o coresight-ctcu-y := coresight-ctcu-core.o obj-$(CONFIG_CORESIGHT_KUNIT_TESTS) += coresight-kunit-tests.o diff --git a/drivers/hwtracing/coresight/coresight-qmi.c b/drivers/hwtracing/coresight/coresight-qmi.c new file mode 100644 index 0000000000000..d93b606e71084 --- /dev/null +++ b/drivers/hwtracing/coresight/coresight-qmi.c @@ -0,0 +1,209 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved. + */ +#include +#include +#include +#include +#include +#include + +#include "coresight-qmi.h" +static LIST_HEAD(qmi_data); + +static int service_coresight_qmi_new_server(struct qmi_handle *qmi, + struct qmi_service *svc) +{ + struct qmi_data *data = container_of(qmi, + struct qmi_data, handle); + + data->s_addr.sq_family = AF_QIPCRTR; + data->s_addr.sq_node = svc->node; + data->s_addr.sq_port = svc->port; + data->service_connected = true; + pr_debug("Connection established between QMI handle and %d service\n", + data->qmi_id); + + return 0; +} + +static void service_coresight_qmi_del_server(struct qmi_handle *qmi, + struct qmi_service *svc) +{ + struct qmi_data *data = container_of(qmi, + struct qmi_data, handle); + data->service_connected = false; + pr_debug("Connection disconnected between QMI handle and %d service\n", + data->qmi_id); +} + +static struct qmi_ops server_ops = { + .new_server = service_coresight_qmi_new_server, + .del_server = service_coresight_qmi_del_server, +}; + +static int coresight_qmi_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *node = pdev->dev.of_node; + struct device_node *child_node; + int ret; + + /** + * Get the instance id and service id of the QMI service connection + * from DT node. Creates QMI handle and register new lookup for each + * QMI connection. + */ + for_each_available_child_of_node(node, child_node) { + struct qmi_data *data; + + data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + ret = of_property_read_u32(child_node, "qmi-id", &data->qmi_id); + if (ret) + return ret; + + ret = of_property_read_u32(child_node, "service-id", &data->service_id); + if (ret) + return ret; + + ret = qmi_handle_init(&data->handle, + CORESIGHT_QMI_MAX_MSG_LEN, + &server_ops, NULL); + if (ret < 0) { + dev_err(dev, "qmi client init failed ret:%d\n", ret); + return ret; + } + + qmi_add_lookup(&data->handle, + data->service_id, + CORESIGHT_QMI_VERSION, + data->qmi_id); + + list_add(&data->node, &qmi_data); + } + + return 0; +} + +/** + * coresight_get_qmi_data() - Get the qmi data struct from qmi_data + * @id: instance id to get the qmi data + * + * Return: qmi data struct on success, NULL on failure. + */ +static struct qmi_data *coresight_get_qmi_data(int id) +{ + struct qmi_data *data; + + list_for_each_entry(data, &qmi_data, node) { + if (data->qmi_id == id) + return data; + } + + return NULL; +} + +/** + * coresight_send_qmi_request() - Send a QMI message to remote subsystem + * @instance_id: QMI Instance id of the remote subsystem + * @msg_id: message id of the request + * @resp_ei: description of how to decode a matching response + * @req_ei: description of how to encode a matching request + * @resp: pointer to the object to decode the response info + * @req: pointer to the object to encode the request info + * @len: max length of the QMI message + * + * Return: 0 on success, negative errno on failure. + */ +int coresight_send_qmi_request(int instance_id, int msg_id, struct qmi_elem_info *resp_ei, + struct qmi_elem_info *req_ei, void *resp, void *req, int len) +{ + struct qmi_txn txn; + int ret; + struct qmi_data *data; + + data = coresight_get_qmi_data(instance_id); + if (!data) { + pr_err("No QMI data for QMI service!\n"); + ret = -EINVAL; + return ret; + } + + if (!data->service_connected) { + pr_err("QMI service not connected!\n"); + ret = -EINVAL; + return ret; + } + + ret = qmi_txn_init(&data->handle, &txn, + resp_ei, + resp); + + if (ret < 0) { + pr_err("QMI tx init failed , ret:%d\n", ret); + return ret; + } + + ret = qmi_send_request(&data->handle, &data->s_addr, + &txn, msg_id, + len, + req_ei, + req); + + if (ret < 0) { + pr_err("QMI send ACK failed, ret:%d\n", ret); + qmi_txn_cancel(&txn); + return ret; + } + + ret = qmi_txn_wait(&txn, msecs_to_jiffies(TIMEOUT_MS)); + if (ret < 0) { + pr_err("QMI qmi txn wait failed, ret:%d\n", ret); + return ret; + } + + return 0; +} +EXPORT_SYMBOL(coresight_send_qmi_request); + +static void coresight_qmi_remove(struct platform_device *pdev) +{ + struct qmi_data *data; + + list_for_each_entry(data, &qmi_data, node) { + qmi_handle_release(&data->handle); + } +} + +static const struct of_device_id coresight_qmi_match[] = { + {.compatible = "qcom,coresight-qmi"}, + {} +}; + +static struct platform_driver coresight_qmi_driver = { + .probe = coresight_qmi_probe, + .remove = coresight_qmi_remove, + .driver = { + .name = "coresight-qmi", + .of_match_table = coresight_qmi_match, + }, +}; + +static int __init coresight_qmi_init(void) +{ + return platform_driver_register(&coresight_qmi_driver); +} +module_init(coresight_qmi_init); + +static void __exit coresight_qmi_exit(void) +{ + platform_driver_unregister(&coresight_qmi_driver); +} +module_exit(coresight_qmi_exit); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("CoreSight QMI driver"); diff --git a/drivers/hwtracing/coresight/coresight-qmi.h b/drivers/hwtracing/coresight/coresight-qmi.h new file mode 100644 index 0000000000000..1d57e46177b8c --- /dev/null +++ b/drivers/hwtracing/coresight/coresight-qmi.h @@ -0,0 +1,107 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved. + */ +#ifndef _CORESIGHT_QMI_H +#define _CORESIGHT_QMI_H + +#include + +#define CORESIGHT_QMI_VERSION (1) + +#define CORESIGHT_QMI_SET_ETM_REQ_V01 (0x002C) +#define CORESIGHT_QMI_SET_ETM_RESP_V01 (0x002C) + +#define CORESIGHT_QMI_MAX_MSG_LEN (50) + +#define TIMEOUT_MS (10000) + +/* Qmi data for the QMI connection */ +struct qmi_data { + u32 qmi_id; + u32 service_id; + struct list_head node; + struct qmi_handle handle; + bool service_connected; + struct sockaddr_qrtr s_addr; +}; + +/** + * QMI service IDs + * + * CORESIGHT_QMI_QDSSC_SVC_ID for remote etm + * CORESIGHT_QMI_QDCP_SVC_ID for STM/TPDM/CTI + */ +enum coresight_qmi_service_id { + CORESIGHT_QMI_QDSSC_SVC_ID = 0x33, + CORESIGHT_QMI_QDCP_SVC_ID = 0xff, +}; + +enum coresight_qmi_instance_id { + CORESIGHT_QMI_INSTANCE_MODEM_V01 = 2, + CORESIGHT_QMI_INSTANCE_WLAN_V01 = 3, + CORESIGHT_QMI_INSTANCE_AOP_V01 = 4, + CORESIGHT_QMI_INSTANCE_ADSP_V01 = 5, + CORESIGHT_QMI_INSTANCE_VENUS_V01 = 6, + CORESIGHT_QMI_INSTANCE_GNSS_V01 = 7, + CORESIGHT_QMI_INSTANCE_SENSOR_V01 = 8, + CORESIGHT_QMI_INSTANCE_AUDIO_V01 = 9, + CORESIGHT_QMI_INSTANCE_VPU_V01 = 10, + CORESIGHT_QMI_INSTANCE_MODEM2_V01 = 11, + CORESIGHT_QMI_INSTANCE_SENSOR2_V01 = 12, + CORESIGHT_QMI_INSTANCE_CDSP_V01 = 13, + CORESIGHT_QMI_INSTANCE_NPU_V01 = 14, + CORESIGHT_QMI_INSTANCE_CDSP_USER_V01 = 15, + CORESIGHT_QMI_INSTANCE_CDSP1_V01 = 16, + CORESIGHT_QMI_INSTANCE_GPDSP0_V01 = 17, + CORESIGHT_QMI_INSTANCE_GPDSP1_V01 = 18, + CORESIGHT_QMI_INSTANCE_TBD_V01 = 19, + CORESIGHT_QMI_INSTANCE_GPDSP0_AUDI0_V01 = 20, + CORESIGHT_QMI_INSTANCE_GPDSP1_AUDI0_V01 = 21, + CORESIGHT_QMI_INSTANCE_MODEM_OEM_V01 = 22, + CORESIGHT_QMI_INSTANCE_ADSP1_V01 = 23, + CORESIGHT_QMI_INSTANCE_ADSP1_AUDIO_V01 = 24, + CORESIGHT_QMI_INSTANCE_ADSP2_V01 = 25, + CORESIGHT_QMI_INSTANCE_ADSP2_AUDIO_V01 = 26, + CORESIGHT_QMI_INSTANCE_CDSP2_V01 = 27, + CORESIGHT_QMI_INSTANCE_CDSP3_V01 = 28, + CORESIGHT_QMI_INSTANCE_SOCCP_V01 = 29, + CORESIGHT_QMI_INSTANCE_QECP_V01 = 30, +}; + +enum coresight_etm_state_enum_type_v01 { + /* To force a 32 bit signed enum. Do not change or use */ + CORESIGHT_ETM_STATE_ENUM_TYPE_MIN_ENUM_VAL_V01 = INT_MIN, + CORESIGHT_ETM_STATE_DISABLED_V01 = 0, + CORESIGHT_ETM_STATE_ENABLED_V01 = 1, + CORESIGHT_ETM_STATE_ENUM_TYPE_MAX_ENUM_VAL_01 = INT_MAX, +}; + +/** + * Set remote etm request message + * + * @state enable/disable state + */ +struct coresight_set_etm_req_msg_v01 { + enum coresight_etm_state_enum_type_v01 state; +}; + +/** + * Set remote etm response message + */ +struct coresight_set_etm_resp_msg_v01 { + struct qmi_response_type_v01 resp; +}; + +#if IS_ENABLED(CONFIG_CORESIGHT_QMI) +extern int coresight_send_qmi_request(int instance_id, int msg_id, + struct qmi_elem_info *resp_ei, + struct qmi_elem_info *req_ei, void *resp, void *req, int len); +#else + +static inline int coresight_send_qmi_request(int instance_id, int msg_id, + struct qmi_elem_info *resp_ei, + struct qmi_elem_info *req_ei, void *resp, void *req, int len) {return NULL; } +#endif + +#endif diff --git a/drivers/hwtracing/coresight/coresight-remote-etm.c b/drivers/hwtracing/coresight/coresight-remote-etm.c new file mode 100644 index 0000000000000..6b24dc70847a3 --- /dev/null +++ b/drivers/hwtracing/coresight/coresight-remote-etm.c @@ -0,0 +1,252 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "coresight-qmi.h" + +#define CORESIGHT_QMI_SET_ETM_REQ_MAX_LEN (7) + +DEFINE_CORESIGHT_DEVLIST(remote_etm_devs, "remote-etm"); + +/** + * struct remote_etm_drvdata - specifics associated to remote etm device + * @dev: the device entity associated to this component + * @csdev: component vitals needed by the framework + * @mutex: lock for seting etm + * @inst_id: the instance id of the remote connection + */ +struct remote_etm_drvdata { + struct device *dev; + struct coresight_device *csdev; + struct mutex mutex; + u32 inst_id; +}; + +/* + * Element info to descrbe the coresight_set_etm_req_msg_v01 struct + * which is used to encode the request. + */ +static struct qmi_elem_info coresight_set_etm_req_msg_v01_ei[] = { + { + .data_type = QMI_UNSIGNED_4_BYTE, + .elem_len = 1, + .elem_size = sizeof(enum coresight_etm_state_enum_type_v01), + .array_type = NO_ARRAY, + .tlv_type = 0x01, + .offset = offsetof(struct coresight_set_etm_req_msg_v01, + state), + .ei_array = NULL, + }, + { + .data_type = QMI_EOTI, + .elem_len = 0, + .elem_size = 0, + .array_type = NO_ARRAY, + .tlv_type = 0, + .offset = 0, + .ei_array = NULL, + }, +}; + +/* + * Element info to describe the coresight_set_etm_resp_msg_v01 struct + * which is used to decode the response. + */ +static struct qmi_elem_info coresight_set_etm_resp_msg_v01_ei[] = { + { + .data_type = QMI_STRUCT, + .elem_len = 1, + .elem_size = sizeof(struct qmi_response_type_v01), + .array_type = NO_ARRAY, + .tlv_type = 0x02, + .offset = offsetof(struct coresight_set_etm_resp_msg_v01, + resp), + .ei_array = qmi_response_type_v01_ei, + }, + { + .data_type = QMI_EOTI, + .elem_len = 0, + .elem_size = 0, + .array_type = NO_ARRAY, + .tlv_type = 0, + .offset = 0, + .ei_array = NULL, + }, +}; + +static int remote_etm_enable(struct coresight_device *csdev, + struct perf_event *event, enum cs_mode mode, + __maybe_unused struct coresight_path *path) +{ + struct remote_etm_drvdata *drvdata = + dev_get_drvdata(csdev->dev.parent); + struct coresight_set_etm_req_msg_v01 req; + struct coresight_set_etm_resp_msg_v01 resp = { { 0, 0 } }; + int ret = 0; + + mutex_lock(&drvdata->mutex); + + if (mode != CS_MODE_SYSFS) { + ret = -EINVAL; + goto err; + } + + if (!coresight_take_mode(csdev, mode)) { + ret = -EBUSY; + goto err; + } + + req.state = CORESIGHT_ETM_STATE_ENABLED_V01; + + ret = coresight_send_qmi_request(drvdata->inst_id, CORESIGHT_QMI_SET_ETM_REQ_V01, + coresight_set_etm_resp_msg_v01_ei, + coresight_set_etm_req_msg_v01_ei, + &resp, &req, CORESIGHT_QMI_SET_ETM_REQ_MAX_LEN); + + if (ret) + goto err; + + if (resp.resp.result != QMI_RESULT_SUCCESS_V01) { + dev_err(drvdata->dev, "QMI request failed 0x%x\n", resp.resp.error); + ret = -EINVAL; + goto err; + } + + mutex_unlock(&drvdata->mutex); + return 0; +err: + coresight_set_mode(csdev, CS_MODE_DISABLED); + mutex_unlock(&drvdata->mutex); + return ret; + +} + +static void remote_etm_disable(struct coresight_device *csdev, + struct perf_event *event) +{ + struct remote_etm_drvdata *drvdata = + dev_get_drvdata(csdev->dev.parent); + struct coresight_set_etm_req_msg_v01 req; + struct coresight_set_etm_resp_msg_v01 resp = { { 0, 0 } }; + int ret = 0; + + mutex_lock(&drvdata->mutex); + + req.state = CORESIGHT_ETM_STATE_DISABLED_V01; + + ret = coresight_send_qmi_request(drvdata->inst_id, CORESIGHT_QMI_SET_ETM_REQ_V01, + coresight_set_etm_resp_msg_v01_ei, + coresight_set_etm_req_msg_v01_ei, + &resp, &req, CORESIGHT_QMI_SET_ETM_REQ_MAX_LEN); + if (ret) + dev_err(drvdata->dev, "Send qmi request failed %d\n", ret); + + if (resp.resp.result != QMI_RESULT_SUCCESS_V01) + dev_err(drvdata->dev, "QMI request failed %d\n", resp.resp.error); + + coresight_set_mode(csdev, CS_MODE_DISABLED); + mutex_unlock(&drvdata->mutex); +} + +static const struct coresight_ops_source remote_etm_source_ops = { + .enable = remote_etm_enable, + .disable = remote_etm_disable, +}; + +static const struct coresight_ops remote_cs_ops = { + .source_ops = &remote_etm_source_ops, +}; + +static int remote_etm_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct coresight_platform_data *pdata; + struct remote_etm_drvdata *drvdata; + struct coresight_desc desc = {0 }; + int ret; + + desc.name = coresight_alloc_device_name(&remote_etm_devs, dev); + if (!desc.name) + return -ENOMEM; + pdata = coresight_get_platform_data(dev); + if (IS_ERR(pdata)) + return PTR_ERR(pdata); + pdev->dev.platform_data = pdata; + + drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); + if (!drvdata) + return -ENOMEM; + + drvdata->dev = dev; + platform_set_drvdata(pdev, drvdata); + + ret = of_property_read_u32(dev->of_node, "qcom,qmi-id", + &drvdata->inst_id); + if (ret) + return ret; + + mutex_init(&drvdata->mutex); + + desc.type = CORESIGHT_DEV_TYPE_SOURCE; + desc.subtype.source_subtype = CORESIGHT_DEV_SUBTYPE_SOURCE_OTHERS; + desc.ops = &remote_cs_ops; + desc.pdata = pdev->dev.platform_data; + desc.dev = &pdev->dev; + drvdata->csdev = coresight_register(&desc); + if (IS_ERR(drvdata->csdev)) { + ret = PTR_ERR(drvdata->csdev); + goto err; + } + + dev_dbg(dev, "Remote ETM initialized\n"); + + return 0; + +err: + return ret; +} + +static void remote_etm_remove(struct platform_device *pdev) +{ + struct remote_etm_drvdata *drvdata = platform_get_drvdata(pdev); + + coresight_unregister(drvdata->csdev); +} + +static const struct of_device_id remote_etm_match[] = { + {.compatible = "qcom,coresight-remote-etm"}, + {} +}; + +static struct platform_driver remote_etm_driver = { + .probe = remote_etm_probe, + .remove = remote_etm_remove, + .driver = { + .name = "coresight-remote-etm", + .of_match_table = remote_etm_match, + }, +}; + +static int __init remote_etm_init(void) +{ + return platform_driver_register(&remote_etm_driver); +} +module_init(remote_etm_init); + +static void __exit remote_etm_exit(void) +{ + platform_driver_unregister(&remote_etm_driver); +} +module_exit(remote_etm_exit); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("CoreSight Remote ETM driver"); diff --git a/drivers/hwtracing/coresight/coresight-sysfs.c b/drivers/hwtracing/coresight/coresight-sysfs.c index feadaf065b531..e3d21c49814d1 100644 --- a/drivers/hwtracing/coresight/coresight-sysfs.c +++ b/drivers/hwtracing/coresight/coresight-sysfs.c @@ -7,6 +7,7 @@ #include #include #include +#include #include "coresight-priv.h" #include "coresight-trace-id.h" @@ -371,18 +372,47 @@ static ssize_t enable_source_store(struct device *dev, } static DEVICE_ATTR_RW(enable_source); +static ssize_t label_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + + const char *str; + int ret = 0; + + ret = fwnode_property_read_string(dev_fwnode(dev), "label", &str); + if (ret == 0) + return scnprintf(buf, PAGE_SIZE, "%s\n", str); + else + return ret; +} +static DEVICE_ATTR_RO(label); + static struct attribute *coresight_sink_attrs[] = { &dev_attr_enable_sink.attr, + &dev_attr_label.attr, NULL, }; ATTRIBUTE_GROUPS(coresight_sink); static struct attribute *coresight_source_attrs[] = { &dev_attr_enable_source.attr, + &dev_attr_label.attr, NULL, }; ATTRIBUTE_GROUPS(coresight_source); +static struct attribute *coresight_link_attrs[] = { + &dev_attr_label.attr, + NULL, +}; +ATTRIBUTE_GROUPS(coresight_link); + +static struct attribute *coresight_helper_attrs[] = { + &dev_attr_label.attr, + NULL, +}; +ATTRIBUTE_GROUPS(coresight_helper); + const struct device_type coresight_dev_type[] = { [CORESIGHT_DEV_TYPE_SINK] = { .name = "sink", @@ -390,6 +420,7 @@ const struct device_type coresight_dev_type[] = { }, [CORESIGHT_DEV_TYPE_LINK] = { .name = "link", + .groups = coresight_link_groups, }, [CORESIGHT_DEV_TYPE_LINKSINK] = { .name = "linksink", @@ -401,6 +432,7 @@ const struct device_type coresight_dev_type[] = { }, [CORESIGHT_DEV_TYPE_HELPER] = { .name = "helper", + .groups = coresight_helper_groups, } }; /* Ensure the enum matches the names and groups */ diff --git a/drivers/hwtracing/coresight/coresight-tgu.c b/drivers/hwtracing/coresight/coresight-tgu.c new file mode 100644 index 0000000000000..b44c876e7cc7e --- /dev/null +++ b/drivers/hwtracing/coresight/coresight-tgu.c @@ -0,0 +1,780 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2024-2025 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "coresight-priv.h" +#include "coresight-tgu.h" + +DEFINE_CORESIGHT_DEVLIST(tgu_devs, "tgu"); + +static int calculate_array_location(struct tgu_drvdata *drvdata, + int step_index, int operation_index, + int reg_index) +{ + int ret = -EINVAL; + + switch (operation_index) { + case TGU_PRIORITY0: + case TGU_PRIORITY1: + case TGU_PRIORITY2: + case TGU_PRIORITY3: + ret = operation_index * (drvdata->max_step) * + (drvdata->max_reg) + + step_index * (drvdata->max_reg) + reg_index; + break; + case TGU_CONDITION_DECODE: + ret = step_index * (drvdata->max_condition_decode) + + reg_index; + break; + case TGU_CONDITION_SELECT: + ret = step_index * (drvdata->max_condition_select) + reg_index; + break; + case TGU_COUNTER: + ret = step_index * (drvdata->max_counter) + reg_index; + break; + case TGU_TIMER: + ret = step_index * (drvdata->max_timer) + reg_index; + break; + default: + break; + } + return ret; +} + +static int check_array_location(struct tgu_drvdata *drvdata, int step, + int ops, int reg) +{ + int result = calculate_array_location(drvdata, step, ops, reg); + + if (result == -EINVAL) + dev_err(&drvdata->csdev->dev, "%s - Fail\n", __func__); + return result; +} + +static ssize_t tgu_dataset_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct tgu_drvdata *drvdata = dev_get_drvdata(dev->parent); + struct tgu_attribute *tgu_attr = + container_of(attr, struct tgu_attribute, attr); + int ret = 0; + + ret = check_array_location(drvdata, tgu_attr->step_index, + tgu_attr->operation_index, tgu_attr->reg_num); + if (ret == -EINVAL) + return ret; + + switch (tgu_attr->operation_index) { + case TGU_PRIORITY0: + case TGU_PRIORITY1: + case TGU_PRIORITY2: + case TGU_PRIORITY3: + return sysfs_emit(buf, "0x%x\n", + drvdata->value_table->priority[calculate_array_location( + drvdata, tgu_attr->step_index, + tgu_attr->operation_index, + tgu_attr->reg_num)]); + case TGU_CONDITION_DECODE: + return sysfs_emit(buf, "0x%x\n", + drvdata->value_table->condition_decode[calculate_array_location( + drvdata, tgu_attr->step_index, + tgu_attr->operation_index, + tgu_attr->reg_num)]); + case TGU_CONDITION_SELECT: + return sysfs_emit(buf, "0x%x\n", + drvdata->value_table->condition_select[calculate_array_location( + drvdata, tgu_attr->step_index, + tgu_attr->operation_index, + tgu_attr->reg_num)]); + case TGU_TIMER: + return sysfs_emit(buf, "0x%x\n", + drvdata->value_table->timer[calculate_array_location( + drvdata, tgu_attr->step_index, tgu_attr->operation_index, + tgu_attr->reg_num)]); + case TGU_COUNTER: + return sysfs_emit(buf, "0x%x\n", + drvdata->value_table->counter[calculate_array_location( + drvdata, tgu_attr->step_index, tgu_attr->operation_index, + tgu_attr->reg_num)]); + default: + break; + } + return -EINVAL; +} + +static ssize_t tgu_dataset_store(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t size) +{ + unsigned long val; + int ret = -EINVAL; + + struct tgu_drvdata *tgu_drvdata = dev_get_drvdata(dev->parent); + struct tgu_attribute *tgu_attr = + container_of(attr, struct tgu_attribute, attr); + + if (kstrtoul(buf, 0, &val)) + return ret; + + ret = check_array_location(tgu_drvdata, tgu_attr->step_index, + tgu_attr->operation_index, tgu_attr->reg_num); + + if (ret == -EINVAL) + return ret; + + guard(spinlock)(&tgu_drvdata->spinlock); + switch (tgu_attr->operation_index) { + case TGU_PRIORITY0: + case TGU_PRIORITY1: + case TGU_PRIORITY2: + case TGU_PRIORITY3: + tgu_drvdata->value_table->priority[calculate_array_location( + tgu_drvdata, tgu_attr->step_index, + tgu_attr->operation_index, + tgu_attr->reg_num)] = val; + ret = size; + break; + case TGU_CONDITION_DECODE: + tgu_drvdata->value_table->condition_decode[calculate_array_location( + tgu_drvdata, tgu_attr->step_index, + tgu_attr->operation_index, + tgu_attr->reg_num)] = val; + ret = size; + break; + case TGU_CONDITION_SELECT: + tgu_drvdata->value_table->condition_select[calculate_array_location( + tgu_drvdata, tgu_attr->step_index, + tgu_attr->operation_index, + tgu_attr->reg_num)] = val; + ret = size; + break; + case TGU_TIMER: + tgu_drvdata->value_table->timer[calculate_array_location( + tgu_drvdata, tgu_attr->step_index, tgu_attr->operation_index, + tgu_attr->reg_num)] = val; + ret = size; + break; + case TGU_COUNTER: + tgu_drvdata->value_table->counter[calculate_array_location( + tgu_drvdata, tgu_attr->step_index, tgu_attr->operation_index, + tgu_attr->reg_num)] = val; + ret = size; + break; + default: + break; + } + return ret; +} + +static umode_t tgu_node_visible(struct kobject *kobject, + struct attribute *attr, + int n) +{ + struct device *dev = kobj_to_dev(kobject); + struct tgu_drvdata *drvdata = dev_get_drvdata(dev->parent); + int ret = SYSFS_GROUP_INVISIBLE; + + struct device_attribute *dev_attr = + container_of(attr, struct device_attribute, attr); + struct tgu_attribute *tgu_attr = + container_of(dev_attr, struct tgu_attribute, attr); + + if (tgu_attr->step_index < drvdata->max_step) { + switch (tgu_attr->operation_index) { + case TGU_PRIORITY0: + case TGU_PRIORITY1: + case TGU_PRIORITY2: + case TGU_PRIORITY3: + ret = (tgu_attr->reg_num < drvdata->max_reg) ? + attr->mode : + 0; + break; + case TGU_CONDITION_DECODE: + ret = (tgu_attr->reg_num < + drvdata->max_condition_decode) ? + attr->mode : + 0; + break; + case TGU_CONDITION_SELECT: + /* 'default' register is at the end of 'select' region */ + if (tgu_attr->reg_num == + drvdata->max_condition_select - 1) + attr->name = "default"; + ret = (tgu_attr->reg_num < + drvdata->max_condition_select) ? + attr->mode : + 0; + break; + case TGU_COUNTER: + if (drvdata->max_counter == 0) + ret = SYSFS_GROUP_INVISIBLE; + else + ret = (tgu_attr->reg_num < + drvdata->max_counter) ? + attr->mode : + 0; + break; + case TGU_TIMER: + if (drvdata->max_timer == 0) + ret = SYSFS_GROUP_INVISIBLE; + else + ret = (tgu_attr->reg_num < + drvdata->max_timer) ? + attr->mode : + 0; + break; + default: + break; + } + } + return ret; +} + +static ssize_t tgu_write_all_hw_regs(struct tgu_drvdata *drvdata) +{ + int i, j, k, ret; + + CS_UNLOCK(drvdata->base); + + for (i = 0; i < drvdata->max_step; i++) { + for (j = 0; j < MAX_PRIORITY; j++) { + for (k = 0; k < drvdata->max_reg; k++) { + + ret = check_array_location(drvdata, i, j, k); + if (ret == -EINVAL) + goto exit; + + tgu_writel(drvdata, + drvdata->value_table->priority + [calculate_array_location( + drvdata, i, j, k)], + PRIORITY_REG_STEP(i, j, k)); + } + } + } + + for (i = 0; i < drvdata->max_step; i++) { + for (j = 0; j < drvdata->max_condition_decode; j++) { + ret = check_array_location(drvdata, i, TGU_CONDITION_DECODE, j); + if (ret == -EINVAL) + goto exit; + + tgu_writel(drvdata, + drvdata->value_table->condition_decode + [calculate_array_location( + drvdata, i, + TGU_CONDITION_DECODE, j)], + CONDITION_DECODE_STEP(i, j)); + } + } + + for (i = 0; i < drvdata->max_step; i++) { + for (j = 0; j < drvdata->max_condition_select; j++) { + ret = check_array_location(drvdata, i, TGU_CONDITION_SELECT, j); + if (ret == -EINVAL) + goto exit; + + tgu_writel(drvdata, + drvdata->value_table->condition_select + [calculate_array_location(drvdata, i, + TGU_CONDITION_SELECT, j)], + CONDITION_SELECT_STEP(i, j)); + } + } + + for (i = 0; i < drvdata->max_step; i++) { + for (j = 0; j < drvdata->max_timer; j++) { + ret = check_array_location(drvdata, i, TGU_TIMER, j); + if (ret == -EINVAL) + goto exit; + + tgu_writel(drvdata, + drvdata->value_table->timer + [calculate_array_location(drvdata, i, + TGU_TIMER, j)], + TIMER_COMPARE_STEP(i, j)); + } + } + + for (i = 0; i < drvdata->max_step; i++) { + for (j = 0; j < drvdata->max_counter; j++) { + ret = check_array_location(drvdata, i, TGU_COUNTER, j); + if (ret == -EINVAL) + goto exit; + + tgu_writel(drvdata, + drvdata->value_table->counter + [calculate_array_location(drvdata, i, + TGU_COUNTER, j)], + COUNTER_COMPARE_STEP(i, j)); + } + } + /* Enable TGU to program the triggers */ + tgu_writel(drvdata, 1, TGU_CONTROL); +exit: + CS_LOCK(drvdata->base); + return ret >= 0 ? 0 : ret; +} + +static void tgu_set_reg_number(struct tgu_drvdata *drvdata) +{ + int num_sense_input; + int num_reg; + u32 devid; + + devid = readl_relaxed(drvdata->base + CORESIGHT_DEVID); + + num_sense_input = TGU_DEVID_SENSE_INPUT(devid); + if (((num_sense_input * NUMBER_BITS_EACH_SIGNAL) % LENGTH_REGISTER) == 0) + num_reg = (num_sense_input * NUMBER_BITS_EACH_SIGNAL) / LENGTH_REGISTER; + else + num_reg = ((num_sense_input * NUMBER_BITS_EACH_SIGNAL) / LENGTH_REGISTER) + 1; + drvdata->max_reg = num_reg; +} + +static void tgu_set_steps(struct tgu_drvdata *drvdata) +{ + int num_steps; + u32 devid; + + devid = readl_relaxed(drvdata->base + CORESIGHT_DEVID); + + num_steps = TGU_DEVID_STEPS(devid); + + drvdata->max_step = num_steps; +} + +static void tgu_set_conditions(struct tgu_drvdata *drvdata) +{ + int num_conditions; + u32 devid; + + devid = readl_relaxed(drvdata->base + CORESIGHT_DEVID); + + num_conditions = TGU_DEVID_CONDITIONS(devid); + drvdata->max_condition_decode = num_conditions; + /* select region has an additional 'default' register */ + drvdata->max_condition_select = num_conditions + 1; +} + +static void tgu_set_timer_counter(struct tgu_drvdata *drvdata) +{ + int num_timers, num_counters; + u32 devid2; + + devid2 = readl_relaxed(drvdata->base + CORESIGHT_DEVID2); + + if (TGU_DEVID2_TIMER0(devid2) && TGU_DEVID2_TIMER1(devid2)) + num_timers = 2; + else if (TGU_DEVID2_TIMER0(devid2) || TGU_DEVID2_TIMER1(devid2)) + num_timers = 1; + else + num_timers = 0; + + if (TGU_DEVID2_COUNTER0(devid2) && TGU_DEVID2_COUNTER1(devid2)) + num_counters = 2; + else if (TGU_DEVID2_COUNTER0(devid2) || TGU_DEVID2_COUNTER1(devid2)) + num_counters = 1; + else + num_counters = 0; + + drvdata->max_timer = num_timers; + drvdata->max_counter = num_counters; +} + +static int tgu_enable(struct coresight_device *csdev, enum cs_mode mode, + void *data) +{ + int ret = 0; + struct tgu_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); + + spin_lock(&drvdata->spinlock); + + if (drvdata->enable) { + spin_unlock(&drvdata->spinlock); + return -EBUSY; + } + ret = tgu_write_all_hw_regs(drvdata); + + if (ret == -EINVAL) + goto exit; + drvdata->enable = true; + +exit: + spin_unlock(&drvdata->spinlock); + return ret; +} + +static int tgu_disable(struct coresight_device *csdev, void *data) +{ + struct tgu_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); + + spin_lock(&drvdata->spinlock); + if (drvdata->enable) { + CS_UNLOCK(drvdata->base); + tgu_writel(drvdata, 0, TGU_CONTROL); + CS_LOCK(drvdata->base); + + drvdata->enable = false; + } + spin_unlock(&drvdata->spinlock); + return 0; +} + +static ssize_t enable_tgu_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + bool enabled; + + struct tgu_drvdata *drvdata = dev_get_drvdata(dev->parent); + + spin_lock(&drvdata->spinlock); + enabled = drvdata->enable; + spin_unlock(&drvdata->spinlock); + + return sysfs_emit(buf, "%d\n", enabled); +} + +/* enable_tgu_store - Configure Trace and Gating Unit (TGU) triggers. */ +static ssize_t enable_tgu_store(struct device *dev, + struct device_attribute *attr, const char *buf, + size_t size) +{ + int ret = 0; + unsigned long val; + struct tgu_drvdata *drvdata = dev_get_drvdata(dev->parent); + + ret = kstrtoul(buf, 0, &val); + if (ret) + return ret; + + if (val) { + ret = pm_runtime_resume_and_get(dev->parent); + if (ret) + return ret; + ret = tgu_enable(drvdata->csdev, CS_MODE_SYSFS, NULL); + if (ret) + pm_runtime_put(dev->parent); + } else { + ret = tgu_disable(drvdata->csdev, NULL); + pm_runtime_put(dev->parent); + } + + if (ret) + return ret; + return size; +} +static DEVICE_ATTR_RW(enable_tgu); + +/* reset_tgu_store - Reset Trace and Gating Unit (TGU) configuration. */ +static ssize_t reset_tgu_store(struct device *dev, + struct device_attribute *attr, const char *buf, + size_t size) +{ + unsigned long value; + struct tgu_drvdata *drvdata = dev_get_drvdata(dev->parent); + int i, j, ret; + + if (kstrtoul(buf, 0, &value) || value == 0) + return -EINVAL; + + if (!drvdata->enable) { + ret = pm_runtime_get_sync(drvdata->dev); + if (ret < 0) { + pm_runtime_put(drvdata->dev); + return ret; + } + } + + spin_lock(&drvdata->spinlock); + CS_UNLOCK(drvdata->base); + + tgu_writel(drvdata, 0, TGU_CONTROL); + + if (drvdata->value_table->priority) + memset(drvdata->value_table->priority, 0, + MAX_PRIORITY * drvdata->max_step * + drvdata->max_reg * sizeof(unsigned int)); + + if (drvdata->value_table->condition_decode) + memset(drvdata->value_table->condition_decode, 0, + drvdata->max_condition_decode * drvdata->max_step * + sizeof(unsigned int)); + + /* Initialize all condition registers to NOT(value=0x1000000) */ + for (i = 0; i < drvdata->max_step; i++) { + for (j = 0; j < drvdata->max_condition_decode; j++) { + drvdata->value_table + ->condition_decode[calculate_array_location( + drvdata, i, TGU_CONDITION_DECODE, j)] = + 0x1000000; + } + } + + if (drvdata->value_table->condition_select) + memset(drvdata->value_table->condition_select, 0, + drvdata->max_condition_select * drvdata->max_step * + sizeof(unsigned int)); + + if (drvdata->value_table->timer) + memset(drvdata->value_table->timer, 0, + (drvdata->max_step) * + (drvdata->max_timer) * + sizeof(unsigned int)); + + if (drvdata->value_table->counter) + memset(drvdata->value_table->counter, 0, + (drvdata->max_step) * + (drvdata->max_counter) * + sizeof(unsigned int)); + + dev_dbg(dev, "Coresight-TGU reset complete\n"); + + CS_LOCK(drvdata->base); + + drvdata->enable = false; + spin_unlock(&drvdata->spinlock); + pm_runtime_put(drvdata->dev); + + return size; +} +static DEVICE_ATTR_WO(reset_tgu); + +static const struct coresight_ops_helper tgu_helper_ops = { + .enable = tgu_enable, + .disable = tgu_disable, +}; + +static const struct coresight_ops tgu_ops = { + .helper_ops = &tgu_helper_ops, +}; + +static struct attribute *tgu_common_attrs[] = { + &dev_attr_enable_tgu.attr, + &dev_attr_reset_tgu.attr, + NULL, +}; + +static const struct attribute_group tgu_common_grp = { + .attrs = tgu_common_attrs, + { NULL }, +}; + +static const struct attribute_group *tgu_attr_groups[] = { + &tgu_common_grp, + PRIORITY_ATTRIBUTE_GROUP_INIT(0, 0), + PRIORITY_ATTRIBUTE_GROUP_INIT(0, 1), + PRIORITY_ATTRIBUTE_GROUP_INIT(0, 2), + PRIORITY_ATTRIBUTE_GROUP_INIT(0, 3), + PRIORITY_ATTRIBUTE_GROUP_INIT(1, 0), + PRIORITY_ATTRIBUTE_GROUP_INIT(1, 1), + PRIORITY_ATTRIBUTE_GROUP_INIT(1, 2), + PRIORITY_ATTRIBUTE_GROUP_INIT(1, 3), + PRIORITY_ATTRIBUTE_GROUP_INIT(2, 0), + PRIORITY_ATTRIBUTE_GROUP_INIT(2, 1), + PRIORITY_ATTRIBUTE_GROUP_INIT(2, 2), + PRIORITY_ATTRIBUTE_GROUP_INIT(2, 3), + PRIORITY_ATTRIBUTE_GROUP_INIT(3, 0), + PRIORITY_ATTRIBUTE_GROUP_INIT(3, 1), + PRIORITY_ATTRIBUTE_GROUP_INIT(3, 2), + PRIORITY_ATTRIBUTE_GROUP_INIT(3, 3), + PRIORITY_ATTRIBUTE_GROUP_INIT(4, 0), + PRIORITY_ATTRIBUTE_GROUP_INIT(4, 1), + PRIORITY_ATTRIBUTE_GROUP_INIT(4, 2), + PRIORITY_ATTRIBUTE_GROUP_INIT(4, 3), + PRIORITY_ATTRIBUTE_GROUP_INIT(5, 0), + PRIORITY_ATTRIBUTE_GROUP_INIT(5, 1), + PRIORITY_ATTRIBUTE_GROUP_INIT(5, 2), + PRIORITY_ATTRIBUTE_GROUP_INIT(5, 3), + PRIORITY_ATTRIBUTE_GROUP_INIT(6, 0), + PRIORITY_ATTRIBUTE_GROUP_INIT(6, 1), + PRIORITY_ATTRIBUTE_GROUP_INIT(6, 2), + PRIORITY_ATTRIBUTE_GROUP_INIT(6, 3), + PRIORITY_ATTRIBUTE_GROUP_INIT(7, 0), + PRIORITY_ATTRIBUTE_GROUP_INIT(7, 1), + PRIORITY_ATTRIBUTE_GROUP_INIT(7, 2), + PRIORITY_ATTRIBUTE_GROUP_INIT(7, 3), + CONDITION_DECODE_ATTRIBUTE_GROUP_INIT(0), + CONDITION_DECODE_ATTRIBUTE_GROUP_INIT(1), + CONDITION_DECODE_ATTRIBUTE_GROUP_INIT(2), + CONDITION_DECODE_ATTRIBUTE_GROUP_INIT(3), + CONDITION_DECODE_ATTRIBUTE_GROUP_INIT(4), + CONDITION_DECODE_ATTRIBUTE_GROUP_INIT(5), + CONDITION_DECODE_ATTRIBUTE_GROUP_INIT(6), + CONDITION_DECODE_ATTRIBUTE_GROUP_INIT(7), + CONDITION_SELECT_ATTRIBUTE_GROUP_INIT(0), + CONDITION_SELECT_ATTRIBUTE_GROUP_INIT(1), + CONDITION_SELECT_ATTRIBUTE_GROUP_INIT(2), + CONDITION_SELECT_ATTRIBUTE_GROUP_INIT(3), + CONDITION_SELECT_ATTRIBUTE_GROUP_INIT(4), + CONDITION_SELECT_ATTRIBUTE_GROUP_INIT(5), + CONDITION_SELECT_ATTRIBUTE_GROUP_INIT(6), + CONDITION_SELECT_ATTRIBUTE_GROUP_INIT(7), + TIMER_ATTRIBUTE_GROUP_INIT(0), + TIMER_ATTRIBUTE_GROUP_INIT(1), + TIMER_ATTRIBUTE_GROUP_INIT(2), + TIMER_ATTRIBUTE_GROUP_INIT(3), + TIMER_ATTRIBUTE_GROUP_INIT(4), + TIMER_ATTRIBUTE_GROUP_INIT(5), + TIMER_ATTRIBUTE_GROUP_INIT(6), + TIMER_ATTRIBUTE_GROUP_INIT(7), + COUNTER_ATTRIBUTE_GROUP_INIT(0), + COUNTER_ATTRIBUTE_GROUP_INIT(1), + COUNTER_ATTRIBUTE_GROUP_INIT(2), + COUNTER_ATTRIBUTE_GROUP_INIT(3), + COUNTER_ATTRIBUTE_GROUP_INIT(4), + COUNTER_ATTRIBUTE_GROUP_INIT(5), + COUNTER_ATTRIBUTE_GROUP_INIT(6), + COUNTER_ATTRIBUTE_GROUP_INIT(7), + NULL, +}; + +static int tgu_probe(struct amba_device *adev, const struct amba_id *id) +{ + int ret = 0; + struct device *dev = &adev->dev; + struct coresight_desc desc = { 0 }; + struct coresight_platform_data *pdata; + struct tgu_drvdata *drvdata; + + desc.name = coresight_alloc_device_name(&tgu_devs, dev); + if (!desc.name) + return -ENOMEM; + + pdata = coresight_get_platform_data(dev); + if (IS_ERR(pdata)) + return PTR_ERR(pdata); + + adev->dev.platform_data = pdata; + + drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); + if (!drvdata) + return -ENOMEM; + + drvdata->dev = &adev->dev; + dev_set_drvdata(dev, drvdata); + + drvdata->base = devm_ioremap_resource(dev, &adev->res); + if (!drvdata->base) + return -ENOMEM; + + spin_lock_init(&drvdata->spinlock); + + tgu_set_reg_number(drvdata); + tgu_set_steps(drvdata); + tgu_set_conditions(drvdata); + tgu_set_timer_counter(drvdata); + + drvdata->value_table = + devm_kzalloc(dev, sizeof(*drvdata->value_table), GFP_KERNEL); + if (!drvdata->value_table) + return -ENOMEM; + + drvdata->value_table->priority = devm_kzalloc( + dev, + MAX_PRIORITY * drvdata->max_reg * drvdata->max_step * + sizeof(*(drvdata->value_table->priority)), + GFP_KERNEL); + + if (!drvdata->value_table->priority) + return -ENOMEM; + + drvdata->value_table->condition_decode = devm_kzalloc( + dev, + drvdata->max_condition_decode * drvdata->max_step * + sizeof(*(drvdata->value_table->condition_decode)), + GFP_KERNEL); + + if (!drvdata->value_table->condition_decode) + return -ENOMEM; + + drvdata->value_table->condition_select = devm_kzalloc( + dev, + drvdata->max_condition_select * drvdata->max_step * + sizeof(*(drvdata->value_table->condition_select)), + GFP_KERNEL); + + if (!drvdata->value_table->condition_select) + return -ENOMEM; + + drvdata->value_table->timer = devm_kzalloc( + dev, + drvdata->max_step * drvdata->max_timer * + sizeof(*(drvdata->value_table->timer)), + GFP_KERNEL); + + if (!drvdata->value_table->timer) + return -ENOMEM; + + drvdata->value_table->counter = devm_kzalloc( + dev, + drvdata->max_step * drvdata->max_counter * + sizeof(*(drvdata->value_table->counter)), + GFP_KERNEL); + + if (!drvdata->value_table->counter) + return -ENOMEM; + + drvdata->enable = false; + desc.type = CORESIGHT_DEV_TYPE_HELPER; + desc.pdata = adev->dev.platform_data; + desc.dev = &adev->dev; + desc.ops = &tgu_ops; + desc.groups = tgu_attr_groups; + + drvdata->csdev = coresight_register(&desc); + if (IS_ERR(drvdata->csdev)) { + ret = PTR_ERR(drvdata->csdev); + goto err; + } + + pm_runtime_put(&adev->dev); + return 0; +err: + pm_runtime_put(&adev->dev); + return ret; +} + +static void tgu_remove(struct amba_device *adev) +{ + struct tgu_drvdata *drvdata = dev_get_drvdata(&adev->dev); + + coresight_unregister(drvdata->csdev); +} + +static const struct amba_id tgu_ids[] = { + { + .id = 0x000f0e00, + .mask = 0x000fffff, + .data = "TGU", + }, + { 0, 0, NULL }, +}; + +MODULE_DEVICE_TABLE(amba, tgu_ids); + +static struct amba_driver tgu_driver = { + .drv = { + .name = "coresight-tgu", + .suppress_bind_attrs = true, + }, + .probe = tgu_probe, + .remove = tgu_remove, + .id_table = tgu_ids, +}; + +module_amba_driver(tgu_driver); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("CoreSight TGU driver"); diff --git a/drivers/hwtracing/coresight/coresight-tgu.h b/drivers/hwtracing/coresight/coresight-tgu.h new file mode 100644 index 0000000000000..be9c87ec7e3ce --- /dev/null +++ b/drivers/hwtracing/coresight/coresight-tgu.h @@ -0,0 +1,255 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2024-2025 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#ifndef _CORESIGHT_TGU_H +#define _CORESIGHT_TGU_H + +/* Register addresses */ +#define TGU_CONTROL 0x0000 +#define CORESIGHT_DEVID2 0xfc0 +/* Register read/write */ +#define tgu_writel(drvdata, val, off) __raw_writel((val), drvdata->base + off) +#define tgu_readl(drvdata, off) __raw_readl(drvdata->base + off) + +#define TGU_DEVID_SENSE_INPUT(devid_val) ((int) BMVAL(devid_val, 10, 17)) +#define TGU_DEVID_STEPS(devid_val) ((int)BMVAL(devid_val, 3, 6)) +#define TGU_DEVID_CONDITIONS(devid_val) ((int)BMVAL(devid_val, 0, 2)) +#define TGU_DEVID2_TIMER0(devid_val) ((int)BMVAL(devid_val, 18, 23)) +#define TGU_DEVID2_TIMER1(devid_val) ((int)BMVAL(devid_val, 13, 17)) +#define TGU_DEVID2_COUNTER0(devid_val) ((int)BMVAL(devid_val, 6, 11)) +#define TGU_DEVID2_COUNTER1(devid_val) ((int)BMVAL(devid_val, 0, 5)) + +#define NUMBER_BITS_EACH_SIGNAL 4 +#define LENGTH_REGISTER 32 + +/* + * TGU configuration space Step configuration + * offset table space layout + * x-------------------------x$ x-------------x$ + * | |$ | |$ + * | | | reserve |$ + * | | | |$ + * |coresight management | |-------------|base+n*0x1D8+0x1F4$ + * | registe | |---> |prioroty[3] |$ + * | | | |-------------|base+n*0x1D8+0x194$ + * | | | |prioroty[2] |$ + * |-------------------------| | |-------------|base+n*0x1D8+0x134$ + * | | | |prioroty[1] |$ + * | step[7] | | |-------------|base+n*0x1D8+0xD4$ + * |-------------------------|->base+0x40+7*0x1D8 | |prioroty[0] |$ + * | | | |-------------|base+n*0x1D8+0x74$ + * | ... | | | condition |$ + * | | | | select |$ + * |-------------------------|->base+0x40+1*0x1D8 | |-------------|base+n*0x1D8+0x60$ + * | | | | condition |$ + * | step[0] |--------------------> | decode |$ + * |-------------------------|-> base+0x40 |-------------|base+n*0x1D8+0x50$ + * | | | |$ + * | Control and status space| |Timer/Counter|$ + * | space | | |$ + * x-------------------------x->base x-------------x base+n*0x1D8+0x40$ + * + */ +#define STEP_OFFSET 0x1D8 +#define PRIORITY_START_OFFSET 0x0074 +#define CONDITION_DECODE_OFFSET 0x0050 +#define CONDITION_SELECT_OFFSET 0x0060 +#define TIMER_START_OFFSET 0x0040 +#define COUNTER_START_OFFSET 0x0048 +#define PRIORITY_OFFSET 0x60 +#define REG_OFFSET 0x4 + +/* Calculate compare step addresses */ +#define PRIORITY_REG_STEP(step, priority, reg)\ + (PRIORITY_START_OFFSET + PRIORITY_OFFSET * priority +\ + REG_OFFSET * reg + STEP_OFFSET * step) + +#define CONDITION_DECODE_STEP(step, decode) \ + (CONDITION_DECODE_OFFSET + REG_OFFSET * decode + STEP_OFFSET * step) + +#define TIMER_COMPARE_STEP(step, timer) \ + (TIMER_START_OFFSET + REG_OFFSET * timer + STEP_OFFSET * step) + +#define COUNTER_COMPARE_STEP(step, counter) \ + (COUNTER_START_OFFSET + REG_OFFSET * counter + STEP_OFFSET * step) + +#define CONDITION_SELECT_STEP(step, select) \ + (CONDITION_SELECT_OFFSET + REG_OFFSET * select + STEP_OFFSET * step) + +#define tgu_dataset_rw(name, step_index, type, reg_num) \ + (&((struct tgu_attribute[]){ { \ + __ATTR(name, 0644, tgu_dataset_show, tgu_dataset_store), \ + step_index, \ + type, \ + reg_num, \ + } })[0].attr.attr) + +#define STEP_PRIORITY(step_index, reg_num, priority) \ + tgu_dataset_rw(reg##reg_num, step_index, TGU_PRIORITY##priority, \ + reg_num) + +#define STEP_DECODE(step_index, reg_num) \ + tgu_dataset_rw(reg##reg_num, step_index, TGU_CONDITION_DECODE, reg_num) + +#define STEP_SELECT(step_index, reg_num) \ + tgu_dataset_rw(reg##reg_num, step_index, TGU_CONDITION_SELECT, reg_num) + +#define STEP_TIMER(step_index, reg_num) \ + tgu_dataset_rw(reg##reg_num, step_index, TGU_TIMER, reg_num) + +#define STEP_COUNTER(step_index, reg_num) \ + tgu_dataset_rw(reg##reg_num, step_index, TGU_COUNTER, reg_num) + +#define STEP_PRIORITY_LIST(step_index, priority) \ + {STEP_PRIORITY(step_index, 0, priority), \ + STEP_PRIORITY(step_index, 1, priority), \ + STEP_PRIORITY(step_index, 2, priority), \ + STEP_PRIORITY(step_index, 3, priority), \ + STEP_PRIORITY(step_index, 4, priority), \ + STEP_PRIORITY(step_index, 5, priority), \ + STEP_PRIORITY(step_index, 6, priority), \ + STEP_PRIORITY(step_index, 7, priority), \ + STEP_PRIORITY(step_index, 8, priority), \ + STEP_PRIORITY(step_index, 9, priority), \ + STEP_PRIORITY(step_index, 10, priority), \ + STEP_PRIORITY(step_index, 11, priority), \ + STEP_PRIORITY(step_index, 12, priority), \ + STEP_PRIORITY(step_index, 13, priority), \ + STEP_PRIORITY(step_index, 14, priority), \ + STEP_PRIORITY(step_index, 15, priority), \ + STEP_PRIORITY(step_index, 16, priority), \ + STEP_PRIORITY(step_index, 17, priority), \ + NULL \ + } + +#define STEP_DECODE_LIST(n) \ + {STEP_DECODE(n, 0), \ + STEP_DECODE(n, 1), \ + STEP_DECODE(n, 2), \ + STEP_DECODE(n, 3), \ + NULL \ + } + +#define STEP_SELECT_LIST(n) \ + {STEP_SELECT(n, 0), \ + STEP_SELECT(n, 1), \ + STEP_SELECT(n, 2), \ + STEP_SELECT(n, 3), \ + STEP_SELECT(n, 4), \ + NULL \ + } + +#define STEP_TIMER_LIST(n) \ + {STEP_TIMER(n, 0), \ + STEP_TIMER(n, 1), \ + NULL \ + } + +#define STEP_COUNTER_LIST(n) \ + {STEP_COUNTER(n, 0), \ + STEP_COUNTER(n, 1), \ + NULL \ + } + +#define PRIORITY_ATTRIBUTE_GROUP_INIT(step, priority)\ + (&(const struct attribute_group){\ + .attrs = (struct attribute*[])STEP_PRIORITY_LIST(step, priority),\ + .is_visible = tgu_node_visible,\ + .name = "step" #step "_priority" #priority \ + }) + +#define CONDITION_DECODE_ATTRIBUTE_GROUP_INIT(step)\ + (&(const struct attribute_group){\ + .attrs = (struct attribute*[])STEP_DECODE_LIST(step),\ + .is_visible = tgu_node_visible,\ + .name = "step" #step "_condition_decode" \ + }) + +#define CONDITION_SELECT_ATTRIBUTE_GROUP_INIT(step)\ + (&(const struct attribute_group){\ + .attrs = (struct attribute*[])STEP_SELECT_LIST(step),\ + .is_visible = tgu_node_visible,\ + .name = "step" #step "_condition_select" \ + }) + +#define TIMER_ATTRIBUTE_GROUP_INIT(step)\ + (&(const struct attribute_group){\ + .attrs = (struct attribute*[])STEP_TIMER_LIST(step),\ + .is_visible = tgu_node_visible,\ + .name = "step" #step "_timer" \ + }) + +#define COUNTER_ATTRIBUTE_GROUP_INIT(step)\ + (&(const struct attribute_group){\ + .attrs = (struct attribute*[])STEP_COUNTER_LIST(step),\ + .is_visible = tgu_node_visible,\ + .name = "step" #step "_counter" \ + }) + +enum operation_index { + TGU_PRIORITY0, + TGU_PRIORITY1, + TGU_PRIORITY2, + TGU_PRIORITY3, + TGU_CONDITION_DECODE, + TGU_CONDITION_SELECT, + TGU_TIMER, + TGU_COUNTER +}; + +/* Maximum priority that TGU supports */ +#define MAX_PRIORITY 4 + +struct tgu_attribute { + struct device_attribute attr; + u32 step_index; + enum operation_index operation_index; + u32 reg_num; +}; + +struct value_table { + unsigned int *priority; + unsigned int *condition_decode; + unsigned int *condition_select; + unsigned int *timer; + unsigned int *counter; +}; + +/** + * struct tgu_drvdata - Data structure for a TGU (Trigger Generator Unit) + * @base: Memory-mapped base address of the TGU device + * @dev: Pointer to the associated device structure + * @csdev: Pointer to the associated coresight device + * @spinlock: Spinlock for handling concurrent access + * @enable: Flag indicating whether the TGU device is enabled + * @value_table: Store given value based on relevant parameters. + * @max_reg: Maximum number of registers + * @max_step: Maximum step size + * @max_condition_decode: Maximum number of condition_decode + * @max_condition_select: Maximum number of condition_select + * @max_timer: Maximum number of timers + * @max_counter: Maximum number of counters + * + * This structure defines the data associated with a TGU device, + * including its base address, device pointers, clock, spinlock for + * synchronization, trigger data pointers, maximum limits for various + * trigger-related parameters, and enable status. + */ +struct tgu_drvdata { + void __iomem *base; + struct device *dev; + struct coresight_device *csdev; + spinlock_t spinlock; + bool enable; + struct value_table *value_table; + int max_reg; + int max_step; + int max_condition_decode; + int max_condition_select; + int max_timer; + int max_counter; +}; + +#endif diff --git a/drivers/i2c/busses/i2c-qcom-geni.c b/drivers/i2c/busses/i2c-qcom-geni.c index 13889f52b6f78..11f1089edf37d 100644 --- a/drivers/i2c/busses/i2c-qcom-geni.c +++ b/drivers/i2c/busses/i2c-qcom-geni.c @@ -870,7 +870,13 @@ static int geni_i2c_probe(struct platform_device *pdev) goto err_clk; } proto = geni_se_read_proto(&gi2c->se); - if (proto != GENI_SE_I2C) { + if (proto == GENI_SE_INVALID_PROTO) { + ret = geni_load_se_firmware(&gi2c->se, GENI_SE_I2C); + if (ret) { + dev_err_probe(dev, ret, "i2c firmware load failed ret: %d\n", ret); + goto err_resources; + } + } else if (proto != GENI_SE_I2C) { ret = dev_err_probe(dev, -ENXIO, "Invalid proto %d\n", proto); goto err_resources; } diff --git a/drivers/media/platform/qcom/iris/iris_buffer.c b/drivers/media/platform/qcom/iris/iris_buffer.c index e5c5a564fcb81..6425e4919e3b0 100644 --- a/drivers/media/platform/qcom/iris/iris_buffer.c +++ b/drivers/media/platform/qcom/iris/iris_buffer.c @@ -205,6 +205,9 @@ static u32 iris_bitstream_buffer_size(struct iris_inst *inst) if (num_mbs > NUM_MBS_4K) { div_factor = 4; base_res_mbs = caps->max_mbpf; + } else { + if (inst->codec == V4L2_PIX_FMT_VP9) + div_factor = 1; } /* @@ -376,7 +379,7 @@ int iris_destroy_internal_buffer(struct iris_inst *inst, struct iris_buffer *buf return 0; } -int iris_destroy_internal_buffers(struct iris_inst *inst, u32 plane) +static int iris_destroy_internal_buffers(struct iris_inst *inst, u32 plane, bool force) { const struct iris_platform_data *platform_data = inst->core->iris_platform_data; struct iris_buffer *buf, *next; @@ -396,6 +399,14 @@ int iris_destroy_internal_buffers(struct iris_inst *inst, u32 plane) for (i = 0; i < len; i++) { buffers = &inst->buffers[internal_buf_type[i]]; list_for_each_entry_safe(buf, next, &buffers->list, list) { + /* + * during stream on, skip destroying internal(DPB) buffer + * if firmware did not return it. + * during close, destroy all buffers irrespectively. + */ + if (!force && buf->attr & BUF_ATTR_QUEUED) + continue; + ret = iris_destroy_internal_buffer(inst, buf); if (ret) return ret; @@ -405,6 +416,16 @@ int iris_destroy_internal_buffers(struct iris_inst *inst, u32 plane) return 0; } +int iris_destroy_all_internal_buffers(struct iris_inst *inst, u32 plane) +{ + return iris_destroy_internal_buffers(inst, plane, true); +} + +int iris_destroy_dequeued_internal_buffers(struct iris_inst *inst, u32 plane) +{ + return iris_destroy_internal_buffers(inst, plane, false); +} + static int iris_release_internal_buffers(struct iris_inst *inst, enum iris_buffer_type buffer_type) { @@ -593,10 +614,13 @@ int iris_vb2_buffer_done(struct iris_inst *inst, struct iris_buffer *buf) vb2 = &vbuf->vb2_buf; - if (buf->flags & V4L2_BUF_FLAG_ERROR) + if (buf->flags & V4L2_BUF_FLAG_ERROR) { state = VB2_BUF_STATE_ERROR; - else - state = VB2_BUF_STATE_DONE; + vb2_set_plane_payload(vb2, 0, 0); + vb2->timestamp = 0; + v4l2_m2m_buf_done(vbuf, state); + return 0; + } vbuf->flags |= buf->flags; @@ -615,7 +639,10 @@ int iris_vb2_buffer_done(struct iris_inst *inst, struct iris_buffer *buf) v4l2_event_queue_fh(&inst->fh, &ev); v4l2_m2m_mark_stopped(m2m_ctx); } + inst->last_buffer_dequeued = true; } + + state = VB2_BUF_STATE_DONE; vb2->timestamp = buf->timestamp; v4l2_m2m_buf_done(vbuf, state); diff --git a/drivers/media/platform/qcom/iris/iris_buffer.h b/drivers/media/platform/qcom/iris/iris_buffer.h index c36b6347b0770..00825ad2dc3a4 100644 --- a/drivers/media/platform/qcom/iris/iris_buffer.h +++ b/drivers/media/platform/qcom/iris/iris_buffer.h @@ -106,7 +106,8 @@ void iris_get_internal_buffers(struct iris_inst *inst, u32 plane); int iris_create_internal_buffers(struct iris_inst *inst, u32 plane); int iris_queue_internal_buffers(struct iris_inst *inst, u32 plane); int iris_destroy_internal_buffer(struct iris_inst *inst, struct iris_buffer *buffer); -int iris_destroy_internal_buffers(struct iris_inst *inst, u32 plane); +int iris_destroy_all_internal_buffers(struct iris_inst *inst, u32 plane); +int iris_destroy_dequeued_internal_buffers(struct iris_inst *inst, u32 plane); int iris_alloc_and_queue_persist_bufs(struct iris_inst *inst); int iris_alloc_and_queue_input_int_bufs(struct iris_inst *inst); int iris_queue_buffer(struct iris_inst *inst, struct iris_buffer *buf); diff --git a/drivers/media/platform/qcom/iris/iris_ctrls.c b/drivers/media/platform/qcom/iris/iris_ctrls.c index b690578256d59..9136b723c0f2a 100644 --- a/drivers/media/platform/qcom/iris/iris_ctrls.c +++ b/drivers/media/platform/qcom/iris/iris_ctrls.c @@ -17,12 +17,20 @@ static inline bool iris_valid_cap_id(enum platform_inst_fw_cap_type cap_id) static enum platform_inst_fw_cap_type iris_get_cap_id(u32 id) { switch (id) { - case V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER: - return DEBLOCK; case V4L2_CID_MPEG_VIDEO_H264_PROFILE: - return PROFILE; + return PROFILE_H264; + case V4L2_CID_MPEG_VIDEO_HEVC_PROFILE: + return PROFILE_HEVC; + case V4L2_CID_MPEG_VIDEO_VP9_PROFILE: + return PROFILE_VP9; case V4L2_CID_MPEG_VIDEO_H264_LEVEL: - return LEVEL; + return LEVEL_H264; + case V4L2_CID_MPEG_VIDEO_HEVC_LEVEL: + return LEVEL_HEVC; + case V4L2_CID_MPEG_VIDEO_VP9_LEVEL: + return LEVEL_VP9; + case V4L2_CID_MPEG_VIDEO_HEVC_TIER: + return TIER; default: return INST_FW_CAP_MAX; } @@ -34,12 +42,20 @@ static u32 iris_get_v4l2_id(enum platform_inst_fw_cap_type cap_id) return 0; switch (cap_id) { - case DEBLOCK: - return V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER; - case PROFILE: + case PROFILE_H264: return V4L2_CID_MPEG_VIDEO_H264_PROFILE; - case LEVEL: + case PROFILE_HEVC: + return V4L2_CID_MPEG_VIDEO_HEVC_PROFILE; + case PROFILE_VP9: + return V4L2_CID_MPEG_VIDEO_VP9_PROFILE; + case LEVEL_H264: return V4L2_CID_MPEG_VIDEO_H264_LEVEL; + case LEVEL_HEVC: + return V4L2_CID_MPEG_VIDEO_HEVC_LEVEL; + case LEVEL_VP9: + return V4L2_CID_MPEG_VIDEO_VP9_LEVEL; + case TIER: + return V4L2_CID_MPEG_VIDEO_HEVC_TIER; default: return 0; } @@ -84,8 +100,6 @@ int iris_ctrls_init(struct iris_inst *inst) if (iris_get_v4l2_id(cap[idx].cap_id)) num_ctrls++; } - if (!num_ctrls) - return -EINVAL; /* Adding 1 to num_ctrls to include V4L2_CID_MIN_BUFFERS_FOR_CAPTURE */ @@ -163,6 +177,7 @@ void iris_session_init_caps(struct iris_core *core) core->inst_fw_caps[cap_id].value = caps[i].value; core->inst_fw_caps[cap_id].flags = caps[i].flags; core->inst_fw_caps[cap_id].hfi_id = caps[i].hfi_id; + core->inst_fw_caps[cap_id].set = caps[i].set; } } diff --git a/drivers/media/platform/qcom/iris/iris_hfi_common.h b/drivers/media/platform/qcom/iris/iris_hfi_common.h index b2c541367fc61..9e6aadb837830 100644 --- a/drivers/media/platform/qcom/iris/iris_hfi_common.h +++ b/drivers/media/platform/qcom/iris/iris_hfi_common.h @@ -140,6 +140,7 @@ struct hfi_subscription_params { u32 color_info; u32 profile; u32 level; + u32 tier; }; u32 iris_hfi_get_v4l2_color_primaries(u32 hfi_primaries); diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c index 64f887d9a17d7..5fc30d54af4dc 100644 --- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c @@ -88,16 +88,29 @@ static int iris_hfi_gen1_sys_pc_prep(struct iris_core *core) static int iris_hfi_gen1_session_open(struct iris_inst *inst) { struct hfi_session_open_pkt packet; + u32 codec = 0; int ret; if (inst->state != IRIS_INST_DEINIT) return -EALREADY; + switch (inst->codec) { + case V4L2_PIX_FMT_H264: + codec = HFI_VIDEO_CODEC_H264; + break; + case V4L2_PIX_FMT_HEVC: + codec = HFI_VIDEO_CODEC_HEVC; + break; + case V4L2_PIX_FMT_VP9: + codec = HFI_VIDEO_CODEC_VP9; + break; + } + packet.shdr.hdr.size = sizeof(struct hfi_session_open_pkt); packet.shdr.hdr.pkt_type = HFI_CMD_SYS_SESSION_INIT; packet.shdr.session_id = inst->session_id; packet.session_domain = HFI_SESSION_TYPE_DEC; - packet.session_codec = HFI_VIDEO_CODEC_H264; + packet.session_codec = codec; reinit_completion(&inst->completion); @@ -208,8 +221,10 @@ static int iris_hfi_gen1_session_stop(struct iris_inst *inst, u32 plane) flush_pkt.flush_type = flush_type; ret = iris_hfi_queue_cmd_write(core, &flush_pkt, flush_pkt.shdr.hdr.size); - if (!ret) + if (!ret) { + inst->flush_responses_pending++; ret = iris_wait_for_session_response(inst, true); + } } return ret; @@ -386,6 +401,8 @@ static int iris_hfi_gen1_session_drain(struct iris_inst *inst, u32 plane) ip_pkt.shdr.hdr.pkt_type = HFI_CMD_SESSION_EMPTY_BUFFER; ip_pkt.shdr.session_id = inst->session_id; ip_pkt.flags = HFI_BUFFERFLAG_EOS; + if (inst->codec == V4L2_PIX_FMT_VP9) + ip_pkt.packet_buffer = 0xdeadb000; return iris_hfi_queue_cmd_write(inst->core, &ip_pkt, ip_pkt.shdr.hdr.size); } @@ -490,14 +507,6 @@ iris_hfi_gen1_packet_session_set_property(struct hfi_session_set_property_pkt *p packet->shdr.hdr.size += sizeof(u32) + sizeof(*wm); break; } - case HFI_PROPERTY_CONFIG_VDEC_POST_LOOP_DEBLOCKER: { - struct hfi_enable *en = prop_data; - u32 *in = pdata; - - en->enable = *in; - packet->shdr.hdr.size += sizeof(u32) + sizeof(*en); - break; - } default: return -EINVAL; } @@ -546,14 +555,15 @@ static int iris_hfi_gen1_set_resolution(struct iris_inst *inst) struct hfi_framesize fs; int ret; - fs.buffer_type = HFI_BUFFER_INPUT; - fs.width = inst->fmt_src->fmt.pix_mp.width; - fs.height = inst->fmt_src->fmt.pix_mp.height; - - ret = hfi_gen1_set_property(inst, ptype, &fs, sizeof(fs)); - if (ret) - return ret; + if (!iris_drc_pending(inst)) { + fs.buffer_type = HFI_BUFFER_INPUT; + fs.width = inst->fmt_src->fmt.pix_mp.width; + fs.height = inst->fmt_src->fmt.pix_mp.height; + ret = hfi_gen1_set_property(inst, ptype, &fs, sizeof(fs)); + if (ret) + return ret; + } fs.buffer_type = HFI_BUFFER_OUTPUT2; fs.width = inst->fmt_dst->fmt.pix_mp.width; fs.height = inst->fmt_dst->fmt.pix_mp.height; @@ -768,8 +778,8 @@ static int iris_hfi_gen1_session_set_config_params(struct iris_inst *inst, u32 p iris_hfi_gen1_set_bufsize}, }; - config_params = core->iris_platform_data->input_config_params; - config_params_size = core->iris_platform_data->input_config_params_size; + config_params = core->iris_platform_data->input_config_params_default; + config_params_size = core->iris_platform_data->input_config_params_default_size; if (V4L2_TYPE_IS_OUTPUT(plane)) { for (i = 0; i < config_params_size; i++) { diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h b/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h index 9f246816a2862..d4d119ca98b0c 100644 --- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h @@ -13,6 +13,8 @@ #define HFI_SESSION_TYPE_DEC 2 #define HFI_VIDEO_CODEC_H264 0x00000002 +#define HFI_VIDEO_CODEC_HEVC 0x00002000 +#define HFI_VIDEO_CODEC_VP9 0x00004000 #define HFI_ERR_NONE 0x0 @@ -65,7 +67,6 @@ #define HFI_PROPERTY_CONFIG_BUFFER_REQUIREMENTS 0x202001 -#define HFI_PROPERTY_CONFIG_VDEC_POST_LOOP_DEBLOCKER 0x1200001 #define HFI_PROPERTY_PARAM_VDEC_DPB_COUNTS 0x120300e #define HFI_PROPERTY_CONFIG_VDEC_ENTROPY 0x1204004 @@ -117,6 +118,8 @@ #define HFI_FRAME_NOTCODED 0x7f002000 #define HFI_FRAME_YUV 0x7f004000 #define HFI_UNUSED_PICT 0x10000000 +#define HFI_BUFFERFLAG_DATACORRUPT 0x00000008 +#define HFI_BUFFERFLAG_DROP_FRAME 0x20000000 struct hfi_pkt_hdr { u32 size; diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c b/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c index b72d503dd7401..8d1ce8a19a45e 100644 --- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c @@ -200,14 +200,14 @@ static void iris_hfi_gen1_event_seq_changed(struct iris_inst *inst, iris_hfi_gen1_read_changed_params(inst, pkt); - if (inst->state != IRIS_INST_ERROR) { - reinit_completion(&inst->flush_completion); + if (inst->state != IRIS_INST_ERROR && !(inst->sub_state & IRIS_INST_SUB_FIRST_IPSC)) { flush_pkt.shdr.hdr.size = sizeof(struct hfi_session_flush_pkt); flush_pkt.shdr.hdr.pkt_type = HFI_CMD_SESSION_FLUSH; flush_pkt.shdr.session_id = inst->session_id; flush_pkt.flush_type = HFI_FLUSH_OUTPUT; - iris_hfi_queue_cmd_write(inst->core, &flush_pkt, flush_pkt.shdr.hdr.size); + if (!iris_hfi_queue_cmd_write(inst->core, &flush_pkt, flush_pkt.shdr.hdr.size)) + inst->flush_responses_pending++; } iris_vdec_src_change(inst); @@ -348,6 +348,10 @@ static void iris_hfi_gen1_session_etb_done(struct iris_inst *inst, void *packet) struct iris_buffer *buf = NULL; bool found = false; + /* EOS buffer sent via drain won't be in v4l2 buffer list */ + if (pkt->packet_buffer == 0xdeadb000) + return; + v4l2_m2m_for_each_src_buf_safe(m2m_ctx, m2m_buffer, n) { buf = to_iris_buffer(&m2m_buffer->vb); if (buf->index == pkt->input_tag) { @@ -408,7 +412,9 @@ static void iris_hfi_gen1_session_ftb_done(struct iris_inst *inst, void *packet) flush_pkt.shdr.hdr.pkt_type = HFI_CMD_SESSION_FLUSH; flush_pkt.shdr.session_id = inst->session_id; flush_pkt.flush_type = HFI_FLUSH_OUTPUT; - iris_hfi_queue_cmd_write(core, &flush_pkt, flush_pkt.shdr.hdr.size); + if (!iris_hfi_queue_cmd_write(core, &flush_pkt, flush_pkt.shdr.hdr.size)) + inst->flush_responses_pending++; + iris_inst_sub_state_change_drain_last(inst); return; @@ -455,7 +461,12 @@ static void iris_hfi_gen1_session_ftb_done(struct iris_inst *inst, void *packet) timestamp_us = timestamp_hi; timestamp_us = (timestamp_us << 32) | timestamp_lo; } else { - flags |= V4L2_BUF_FLAG_LAST; + if (pkt->stream_id == 1 && !inst->last_buffer_dequeued) { + if (iris_drc_pending(inst)) { + flags |= V4L2_BUF_FLAG_LAST; + inst->last_buffer_dequeued = true; + } + } } buf->timestamp = timestamp_us; @@ -481,6 +492,12 @@ static void iris_hfi_gen1_session_ftb_done(struct iris_inst *inst, void *packet) buf->attr |= BUF_ATTR_DEQUEUED; buf->attr |= BUF_ATTR_BUFFER_DONE; + if (hfi_flags & HFI_BUFFERFLAG_DATACORRUPT) + flags |= V4L2_BUF_FLAG_ERROR; + + if (hfi_flags & HFI_BUFFERFLAG_DROP_FRAME) + flags |= V4L2_BUF_FLAG_ERROR; + buf->flags |= flags; iris_vb2_buffer_done(inst, buf); @@ -558,7 +575,6 @@ static void iris_hfi_gen1_handle_response(struct iris_core *core, void *response const struct iris_hfi_gen1_response_pkt_info *pkt_info; struct device *dev = core->dev; struct hfi_session_pkt *pkt; - struct completion *done; struct iris_inst *inst; bool found = false; u32 i; @@ -619,9 +635,12 @@ static void iris_hfi_gen1_handle_response(struct iris_core *core, void *response if (shdr->error_type != HFI_ERR_NONE) iris_inst_change_state(inst, IRIS_INST_ERROR); - done = pkt_info->pkt == HFI_MSG_SESSION_FLUSH ? - &inst->flush_completion : &inst->completion; - complete(done); + if (pkt_info->pkt == HFI_MSG_SESSION_FLUSH) { + if (!(--inst->flush_responses_pending)) + complete(&inst->flush_completion); + } else { + complete(&inst->completion); + } } mutex_unlock(&inst->lock); diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c b/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c index a908b41e2868f..7ca5ae13d62b9 100644 --- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c @@ -178,7 +178,7 @@ static int iris_hfi_gen2_set_crop_offsets(struct iris_inst *inst) sizeof(u64)); } -static int iris_hfi_gen2_set_bit_dpeth(struct iris_inst *inst) +static int iris_hfi_gen2_set_bit_depth(struct iris_inst *inst) { struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); @@ -295,7 +295,19 @@ static int iris_hfi_gen2_set_profile(struct iris_inst *inst) { struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); - u32 profile = inst->fw_caps[PROFILE].value; + u32 profile = 0; + + switch (inst->codec) { + case V4L2_PIX_FMT_HEVC: + profile = inst->fw_caps[PROFILE_HEVC].value; + break; + case V4L2_PIX_FMT_VP9: + profile = inst->fw_caps[PROFILE_VP9].value; + break; + case V4L2_PIX_FMT_H264: + profile = inst->fw_caps[PROFILE_H264].value; + break; + } inst_hfi_gen2->src_subcr_params.profile = profile; @@ -312,7 +324,19 @@ static int iris_hfi_gen2_set_level(struct iris_inst *inst) { struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); - u32 level = inst->fw_caps[LEVEL].value; + u32 level = 0; + + switch (inst->codec) { + case V4L2_PIX_FMT_HEVC: + level = inst->fw_caps[LEVEL_HEVC].value; + break; + case V4L2_PIX_FMT_VP9: + level = inst->fw_caps[LEVEL_VP9].value; + break; + case V4L2_PIX_FMT_H264: + level = inst->fw_caps[LEVEL_H264].value; + break; + } inst_hfi_gen2->src_subcr_params.level = level; @@ -367,18 +391,35 @@ static int iris_hfi_gen2_set_linear_stride_scanline(struct iris_inst *inst) sizeof(u64)); } +static int iris_hfi_gen2_set_tier(struct iris_inst *inst) +{ + struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); + u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); + u32 tier = inst->fw_caps[TIER].value; + + inst_hfi_gen2->src_subcr_params.tier = tier; + + return iris_hfi_gen2_session_set_property(inst, + HFI_PROP_TIER, + HFI_HOST_FLAGS_NONE, + port, + HFI_PAYLOAD_U32_ENUM, + &tier, + sizeof(u32)); +} + static int iris_hfi_gen2_session_set_config_params(struct iris_inst *inst, u32 plane) { struct iris_core *core = inst->core; - u32 config_params_size, i, j; - const u32 *config_params; + u32 config_params_size = 0, i, j; + const u32 *config_params = NULL; int ret; static const struct iris_hfi_prop_type_handle prop_type_handle_arr[] = { {HFI_PROP_BITSTREAM_RESOLUTION, iris_hfi_gen2_set_bitstream_resolution }, {HFI_PROP_CROP_OFFSETS, iris_hfi_gen2_set_crop_offsets }, {HFI_PROP_CODED_FRAMES, iris_hfi_gen2_set_coded_frames }, - {HFI_PROP_LUMA_CHROMA_BIT_DEPTH, iris_hfi_gen2_set_bit_dpeth }, + {HFI_PROP_LUMA_CHROMA_BIT_DEPTH, iris_hfi_gen2_set_bit_depth }, {HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT, iris_hfi_gen2_set_min_output_count }, {HFI_PROP_PIC_ORDER_CNT_TYPE, iris_hfi_gen2_set_picture_order_count }, {HFI_PROP_SIGNAL_COLOR_INFO, iris_hfi_gen2_set_colorspace }, @@ -386,11 +427,27 @@ static int iris_hfi_gen2_session_set_config_params(struct iris_inst *inst, u32 p {HFI_PROP_LEVEL, iris_hfi_gen2_set_level }, {HFI_PROP_COLOR_FORMAT, iris_hfi_gen2_set_colorformat }, {HFI_PROP_LINEAR_STRIDE_SCANLINE, iris_hfi_gen2_set_linear_stride_scanline }, + {HFI_PROP_TIER, iris_hfi_gen2_set_tier }, }; if (V4L2_TYPE_IS_OUTPUT(plane)) { - config_params = core->iris_platform_data->input_config_params; - config_params_size = core->iris_platform_data->input_config_params_size; + switch (inst->codec) { + case V4L2_PIX_FMT_H264: + config_params = core->iris_platform_data->input_config_params_default; + config_params_size = + core->iris_platform_data->input_config_params_default_size; + break; + case V4L2_PIX_FMT_HEVC: + config_params = core->iris_platform_data->input_config_params_hevc; + config_params_size = + core->iris_platform_data->input_config_params_hevc_size; + break; + case V4L2_PIX_FMT_VP9: + config_params = core->iris_platform_data->input_config_params_vp9; + config_params_size = + core->iris_platform_data->input_config_params_vp9_size; + break; + } } else { config_params = core->iris_platform_data->output_config_params; config_params_size = core->iris_platform_data->output_config_params_size; @@ -416,7 +473,19 @@ static int iris_hfi_gen2_session_set_config_params(struct iris_inst *inst, u32 p static int iris_hfi_gen2_session_set_codec(struct iris_inst *inst) { struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); - u32 codec = HFI_CODEC_DECODE_AVC; + u32 codec = 0; + + switch (inst->codec) { + case V4L2_PIX_FMT_H264: + codec = HFI_CODEC_DECODE_AVC; + break; + case V4L2_PIX_FMT_HEVC: + codec = HFI_CODEC_DECODE_HEVC; + break; + case V4L2_PIX_FMT_VP9: + codec = HFI_CODEC_DECODE_VP9; + break; + } iris_hfi_gen2_packet_session_property(inst, HFI_PROP_CODEC, @@ -548,8 +617,8 @@ static int iris_hfi_gen2_subscribe_change_param(struct iris_inst *inst, u32 plan struct hfi_subscription_params subsc_params; u32 prop_type, payload_size, payload_type; struct iris_core *core = inst->core; - const u32 *change_param; - u32 change_param_size; + const u32 *change_param = NULL; + u32 change_param_size = 0; u32 payload[32] = {0}; u32 hfi_port = 0, i; int ret; @@ -560,8 +629,23 @@ static int iris_hfi_gen2_subscribe_change_param(struct iris_inst *inst, u32 plan return 0; } - change_param = core->iris_platform_data->input_config_params; - change_param_size = core->iris_platform_data->input_config_params_size; + switch (inst->codec) { + case V4L2_PIX_FMT_H264: + change_param = core->iris_platform_data->input_config_params_default; + change_param_size = + core->iris_platform_data->input_config_params_default_size; + break; + case V4L2_PIX_FMT_HEVC: + change_param = core->iris_platform_data->input_config_params_hevc; + change_param_size = + core->iris_platform_data->input_config_params_hevc_size; + break; + case V4L2_PIX_FMT_VP9: + change_param = core->iris_platform_data->input_config_params_vp9; + change_param_size = + core->iris_platform_data->input_config_params_vp9_size; + break; + } payload[0] = HFI_MODE_PORT_SETTINGS_CHANGE; @@ -608,6 +692,11 @@ static int iris_hfi_gen2_subscribe_change_param(struct iris_inst *inst, u32 plan payload_size = sizeof(u32); payload_type = HFI_PAYLOAD_U32; break; + case HFI_PROP_LUMA_CHROMA_BIT_DEPTH: + payload[0] = subsc_params.bit_depth; + payload_size = sizeof(u32); + payload_type = HFI_PAYLOAD_U32; + break; case HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT: payload[0] = subsc_params.fw_min_count; payload_size = sizeof(u32); @@ -633,6 +722,11 @@ static int iris_hfi_gen2_subscribe_change_param(struct iris_inst *inst, u32 plan payload_size = sizeof(u32); payload_type = HFI_PAYLOAD_U32; break; + case HFI_PROP_TIER: + payload[0] = subsc_params.tier; + payload_size = sizeof(u32); + payload_type = HFI_PAYLOAD_U32; + break; default: prop_type = 0; ret = -EINVAL; @@ -659,8 +753,8 @@ static int iris_hfi_gen2_subscribe_change_param(struct iris_inst *inst, u32 plan static int iris_hfi_gen2_subscribe_property(struct iris_inst *inst, u32 plane) { struct iris_core *core = inst->core; - u32 subscribe_prop_size, i; - const u32 *subcribe_prop; + u32 subscribe_prop_size = 0, i; + const u32 *subcribe_prop = NULL; u32 payload[32] = {0}; payload[0] = HFI_MODE_PROPERTY; @@ -669,8 +763,23 @@ static int iris_hfi_gen2_subscribe_property(struct iris_inst *inst, u32 plane) subscribe_prop_size = core->iris_platform_data->dec_input_prop_size; subcribe_prop = core->iris_platform_data->dec_input_prop; } else { - subscribe_prop_size = core->iris_platform_data->dec_output_prop_size; - subcribe_prop = core->iris_platform_data->dec_output_prop; + switch (inst->codec) { + case V4L2_PIX_FMT_H264: + subcribe_prop = core->iris_platform_data->dec_output_prop_avc; + subscribe_prop_size = + core->iris_platform_data->dec_output_prop_avc_size; + break; + case V4L2_PIX_FMT_HEVC: + subcribe_prop = core->iris_platform_data->dec_output_prop_hevc; + subscribe_prop_size = + core->iris_platform_data->dec_output_prop_hevc_size; + break; + case V4L2_PIX_FMT_VP9: + subcribe_prop = core->iris_platform_data->dec_output_prop_vp9; + subscribe_prop_size = + core->iris_platform_data->dec_output_prop_vp9_size; + break; + } } for (i = 0; i < subscribe_prop_size; i++) diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h b/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h index 806f8bb7f505d..5f13dc11bea53 100644 --- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h @@ -46,6 +46,7 @@ #define HFI_PROP_CROP_OFFSETS 0x03000105 #define HFI_PROP_PROFILE 0x03000107 #define HFI_PROP_LEVEL 0x03000108 +#define HFI_PROP_TIER 0x03000109 #define HFI_PROP_STAGE 0x0300010a #define HFI_PROP_PIPE 0x0300010b #define HFI_PROP_LUMA_CHROMA_BIT_DEPTH 0x0300010f @@ -104,6 +105,9 @@ enum hfi_color_format { enum hfi_codec_type { HFI_CODEC_DECODE_AVC = 1, HFI_CODEC_ENCODE_AVC = 2, + HFI_CODEC_DECODE_HEVC = 3, + HFI_CODEC_ENCODE_HEVC = 4, + HFI_CODEC_DECODE_VP9 = 5, }; enum hfi_picture_type { @@ -113,6 +117,7 @@ enum hfi_picture_type { HFI_PICTURE_I = 0x00000008, HFI_PICTURE_CRA = 0x00000010, HFI_PICTURE_BLA = 0x00000020, + HFI_PICTURE_NOSHOW = 0x00000040, }; enum hfi_buffer_type { diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c b/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c index b75a01641d5d4..a8c30fc5c0d06 100644 --- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c @@ -91,7 +91,9 @@ static int iris_hfi_gen2_get_driver_buffer_flags(struct iris_inst *inst, u32 hfi struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); u32 driver_flags = 0; - if (inst_hfi_gen2->hfi_frame_info.picture_type & keyframe) + if (inst_hfi_gen2->hfi_frame_info.picture_type & HFI_PICTURE_NOSHOW) + driver_flags |= V4L2_BUF_FLAG_ERROR; + else if (inst_hfi_gen2->hfi_frame_info.picture_type & keyframe) driver_flags |= V4L2_BUF_FLAG_KEYFRAME; else if (inst_hfi_gen2->hfi_frame_info.picture_type & HFI_PICTURE_P) driver_flags |= V4L2_BUF_FLAG_PFRAME; @@ -265,7 +267,8 @@ static int iris_hfi_gen2_handle_system_error(struct iris_core *core, { struct iris_inst *instance; - dev_err(core->dev, "received system error of type %#x\n", pkt->type); + if (pkt) + dev_err(core->dev, "received system error of type %#x\n", pkt->type); core->state = IRIS_CORE_ERROR; @@ -377,6 +380,11 @@ static int iris_hfi_gen2_handle_output_buffer(struct iris_inst *inst, buf->flags = iris_hfi_gen2_get_driver_buffer_flags(inst, hfi_buffer->flags); + if (!buf->data_size && inst->state == IRIS_INST_STREAMING && + !(hfi_buffer->flags & HFI_BUF_FW_FLAG_LAST)) { + buf->flags |= V4L2_BUF_FLAG_ERROR; + } + return 0; } @@ -563,9 +571,23 @@ static void iris_hfi_gen2_read_input_subcr_params(struct iris_inst *inst) inst->crop.width = pixmp_ip->width - ((subsc_params.crop_offsets[1] >> 16) & 0xFFFF) - inst->crop.left; - inst->fw_caps[PROFILE].value = subsc_params.profile; - inst->fw_caps[LEVEL].value = subsc_params.level; + switch (inst->codec) { + case V4L2_PIX_FMT_HEVC: + inst->fw_caps[PROFILE_HEVC].value = subsc_params.profile; + inst->fw_caps[LEVEL_HEVC].value = subsc_params.level; + break; + case V4L2_PIX_FMT_VP9: + inst->fw_caps[PROFILE_VP9].value = subsc_params.profile; + inst->fw_caps[LEVEL_VP9].value = subsc_params.level; + break; + case V4L2_PIX_FMT_H264: + inst->fw_caps[PROFILE_H264].value = subsc_params.profile; + inst->fw_caps[LEVEL_H264].value = subsc_params.level; + break; + } + inst->fw_caps[POC].value = subsc_params.pic_order_cnt; + inst->fw_caps[TIER].value = subsc_params.tier; if (subsc_params.bit_depth != BIT_DEPTH_8 || !(subsc_params.coded_frames & HFI_BITMASK_FRAME_MBS_ONLY_FLAG)) { @@ -636,9 +658,6 @@ static int iris_hfi_gen2_handle_session_property(struct iris_inst *inst, { struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); - if (pkt->port != HFI_PORT_BITSTREAM) - return 0; - if (pkt->flags & HFI_FW_FLAGS_INFORMATION) return 0; @@ -650,6 +669,9 @@ static int iris_hfi_gen2_handle_session_property(struct iris_inst *inst, inst_hfi_gen2->src_subcr_params.crop_offsets[0] = pkt->payload[0]; inst_hfi_gen2->src_subcr_params.crop_offsets[1] = pkt->payload[1]; break; + case HFI_PROP_LUMA_CHROMA_BIT_DEPTH: + inst_hfi_gen2->src_subcr_params.bit_depth = pkt->payload[0]; + break; case HFI_PROP_CODED_FRAMES: inst_hfi_gen2->src_subcr_params.coded_frames = pkt->payload[0]; break; @@ -668,6 +690,9 @@ static int iris_hfi_gen2_handle_session_property(struct iris_inst *inst, case HFI_PROP_LEVEL: inst_hfi_gen2->src_subcr_params.level = pkt->payload[0]; break; + case HFI_PROP_TIER: + inst_hfi_gen2->src_subcr_params.tier = pkt->payload[0]; + break; case HFI_PROP_PICTURE_TYPE: inst_hfi_gen2->hfi_frame_info.picture_type = pkt->payload[0]; break; @@ -791,8 +816,21 @@ static void iris_hfi_gen2_init_src_change_param(struct iris_inst *inst) full_range, video_format, video_signal_type_present_flag); - subsc_params->profile = inst->fw_caps[PROFILE].value; - subsc_params->level = inst->fw_caps[LEVEL].value; + switch (inst->codec) { + case V4L2_PIX_FMT_HEVC: + subsc_params->profile = inst->fw_caps[PROFILE_HEVC].value; + subsc_params->level = inst->fw_caps[LEVEL_HEVC].value; + break; + case V4L2_PIX_FMT_VP9: + subsc_params->profile = inst->fw_caps[PROFILE_VP9].value; + subsc_params->level = inst->fw_caps[LEVEL_VP9].value; + break; + case V4L2_PIX_FMT_H264: + subsc_params->profile = inst->fw_caps[PROFILE_H264].value; + subsc_params->level = inst->fw_caps[LEVEL_H264].value; + break; + } + subsc_params->pic_order_cnt = inst->fw_caps[POC].value; subsc_params->bit_depth = inst->fw_caps[BIT_DEPTH].value; if (inst->fw_caps[CODED_FRAMES].value == diff --git a/drivers/media/platform/qcom/iris/iris_hfi_queue.c b/drivers/media/platform/qcom/iris/iris_hfi_queue.c index fac7df0c4d1ae..221dcd09e1e10 100644 --- a/drivers/media/platform/qcom/iris/iris_hfi_queue.c +++ b/drivers/media/platform/qcom/iris/iris_hfi_queue.c @@ -113,7 +113,7 @@ int iris_hfi_queue_cmd_write_locked(struct iris_core *core, void *pkt, u32 pkt_s { struct iris_iface_q_info *q_info = &core->command_queue; - if (core->state == IRIS_CORE_ERROR) + if (core->state == IRIS_CORE_ERROR || core->state == IRIS_CORE_DEINIT) return -EINVAL; if (!iris_hfi_queue_write(q_info, pkt, pkt_size)) { diff --git a/drivers/media/platform/qcom/iris/iris_instance.h b/drivers/media/platform/qcom/iris/iris_instance.h index caa3c65070061..0e1f5799b72d9 100644 --- a/drivers/media/platform/qcom/iris/iris_instance.h +++ b/drivers/media/platform/qcom/iris/iris_instance.h @@ -27,6 +27,7 @@ * @crop: structure of crop info * @completion: structure of signal completions * @flush_completion: structure of signal completions for flush cmd + * @flush_responses_pending: counter to track number of pending flush responses * @fw_caps: array of supported instance firmware capabilities * @buffers: array of different iris buffers * @fw_min_count: minimnum count of buffers needed by fw @@ -42,6 +43,8 @@ * @sequence_out: a sequence counter for output queue * @tss: timestamp metadata * @metadata_idx: index for metadata buffer + * @codec: codec type + * @last_buffer_dequeued: a flag to indicate that last buffer is sent by driver */ struct iris_inst { @@ -57,6 +60,7 @@ struct iris_inst { struct iris_hfi_rect_desc crop; struct completion completion; struct completion flush_completion; + u32 flush_responses_pending; struct platform_inst_fw_cap fw_caps[INST_FW_CAP_MAX]; struct iris_buffers buffers[BUF_TYPE_MAX]; u32 fw_min_count; @@ -72,6 +76,8 @@ struct iris_inst { u32 sequence_out; struct iris_ts_metadata tss[VIDEO_MAX_FRAME]; u32 metadata_idx; + u32 codec; + bool last_buffer_dequeued; }; #endif diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/drivers/media/platform/qcom/iris/iris_platform_common.h index ac76d9e1ef9c1..adafdce8a856f 100644 --- a/drivers/media/platform/qcom/iris/iris_platform_common.h +++ b/drivers/media/platform/qcom/iris/iris_platform_common.h @@ -21,6 +21,7 @@ struct iris_inst; #define DEFAULT_MAX_HOST_BUF_COUNT 64 #define DEFAULT_MAX_HOST_BURST_BUF_COUNT 256 #define DEFAULT_FPS 30 +#define NUM_MBS_8K ((8192 * 4352) / 256) enum stage_type { STAGE_1 = 1, @@ -80,8 +81,12 @@ struct platform_inst_caps { }; enum platform_inst_fw_cap_type { - PROFILE = 1, - LEVEL, + PROFILE_H264 = 1, + PROFILE_HEVC, + PROFILE_VP9, + LEVEL_H264, + LEVEL_HEVC, + LEVEL_VP9, INPUT_BUF_HOST_MAX_COUNT, STAGE, PIPE, @@ -89,7 +94,7 @@ enum platform_inst_fw_cap_type { CODED_FRAMES, BIT_DEPTH, RAP_FRAME, - DEBLOCK, + TIER, INST_FW_CAP_MAX, }; @@ -172,15 +177,24 @@ struct iris_platform_data { struct ubwc_config_data *ubwc_config; u32 num_vpp_pipe; u32 max_session_count; + /* max number of macroblocks per frame supported */ u32 max_core_mbpf; - const u32 *input_config_params; - unsigned int input_config_params_size; + const u32 *input_config_params_default; + unsigned int input_config_params_default_size; + const u32 *input_config_params_hevc; + unsigned int input_config_params_hevc_size; + const u32 *input_config_params_vp9; + unsigned int input_config_params_vp9_size; const u32 *output_config_params; unsigned int output_config_params_size; const u32 *dec_input_prop; unsigned int dec_input_prop_size; - const u32 *dec_output_prop; - unsigned int dec_output_prop_size; + const u32 *dec_output_prop_avc; + unsigned int dec_output_prop_avc_size; + const u32 *dec_output_prop_hevc; + unsigned int dec_output_prop_hevc_size; + const u32 *dec_output_prop_vp9; + unsigned int dec_output_prop_vp9_size; const u32 *dec_ip_int_buf_tbl; unsigned int dec_ip_int_buf_tbl_size; const u32 *dec_op_int_buf_tbl; diff --git a/drivers/media/platform/qcom/iris/iris_platform_gen2.c b/drivers/media/platform/qcom/iris/iris_platform_gen2.c index 1e69ba15db0fd..d3026b2bcb708 100644 --- a/drivers/media/platform/qcom/iris/iris_platform_gen2.c +++ b/drivers/media/platform/qcom/iris/iris_platform_gen2.c @@ -17,7 +17,7 @@ static struct platform_inst_fw_cap inst_fw_cap_sm8550[] = { { - .cap_id = PROFILE, + .cap_id = PROFILE_H264, .min = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE, .max = V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH, .step_or_mask = BIT(V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) | @@ -31,7 +31,29 @@ static struct platform_inst_fw_cap inst_fw_cap_sm8550[] = { .set = iris_set_u32_enum, }, { - .cap_id = LEVEL, + .cap_id = PROFILE_HEVC, + .min = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN, + .max = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE, + .step_or_mask = BIT(V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN) | + BIT(V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE), + .value = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN, + .hfi_id = HFI_PROP_PROFILE, + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU, + .set = iris_set_u32_enum, + }, + { + .cap_id = PROFILE_VP9, + .min = V4L2_MPEG_VIDEO_VP9_PROFILE_0, + .max = V4L2_MPEG_VIDEO_VP9_PROFILE_2, + .step_or_mask = BIT(V4L2_MPEG_VIDEO_VP9_PROFILE_0) | + BIT(V4L2_MPEG_VIDEO_VP9_PROFILE_2), + .value = V4L2_MPEG_VIDEO_VP9_PROFILE_0, + .hfi_id = HFI_PROP_PROFILE, + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU, + .set = iris_set_u32_enum, + }, + { + .cap_id = LEVEL_H264, .min = V4L2_MPEG_VIDEO_H264_LEVEL_1_0, .max = V4L2_MPEG_VIDEO_H264_LEVEL_6_2, .step_or_mask = BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_0) | @@ -59,6 +81,60 @@ static struct platform_inst_fw_cap inst_fw_cap_sm8550[] = { .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU, .set = iris_set_u32_enum, }, + { + .cap_id = LEVEL_HEVC, + .min = V4L2_MPEG_VIDEO_HEVC_LEVEL_1, + .max = V4L2_MPEG_VIDEO_HEVC_LEVEL_6_2, + .step_or_mask = BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_1) | + BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_2) | + BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_2_1) | + BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_3) | + BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_3_1) | + BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_4) | + BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_4_1) | + BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_5) | + BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_5_1) | + BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_5_2) | + BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_6) | + BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_6_1) | + BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_6_2), + .value = V4L2_MPEG_VIDEO_HEVC_LEVEL_6_1, + .hfi_id = HFI_PROP_LEVEL, + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU, + .set = iris_set_u32_enum, + }, + { + .cap_id = LEVEL_VP9, + .min = V4L2_MPEG_VIDEO_VP9_LEVEL_1_0, + .max = V4L2_MPEG_VIDEO_VP9_LEVEL_6_0, + .step_or_mask = BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_1_0) | + BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_1_1) | + BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_2_0) | + BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_2_1) | + BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_3_0) | + BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_3_1) | + BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_4_0) | + BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_4_1) | + BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_5_0) | + BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_5_1) | + BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_5_2) | + BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_6_0), + .value = V4L2_MPEG_VIDEO_VP9_LEVEL_6_0, + .hfi_id = HFI_PROP_LEVEL, + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU, + .set = iris_set_u32_enum, + }, + { + .cap_id = TIER, + .min = V4L2_MPEG_VIDEO_HEVC_TIER_MAIN, + .max = V4L2_MPEG_VIDEO_HEVC_TIER_HIGH, + .step_or_mask = BIT(V4L2_MPEG_VIDEO_HEVC_TIER_MAIN) | + BIT(V4L2_MPEG_VIDEO_HEVC_TIER_HIGH), + .value = V4L2_MPEG_VIDEO_HEVC_TIER_HIGH, + .hfi_id = HFI_PROP_TIER, + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU, + .set = iris_set_u32_enum, + }, { .cap_id = INPUT_BUF_HOST_MAX_COUNT, .min = DEFAULT_MAX_HOST_BUF_COUNT, @@ -181,9 +257,10 @@ static struct tz_cp_config tz_cp_config_sm8550 = { .cp_nonpixel_size = 0x24800000, }; -static const u32 sm8550_vdec_input_config_params[] = { +static const u32 sm8550_vdec_input_config_params_default[] = { HFI_PROP_BITSTREAM_RESOLUTION, HFI_PROP_CROP_OFFSETS, + HFI_PROP_LUMA_CHROMA_BIT_DEPTH, HFI_PROP_CODED_FRAMES, HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT, HFI_PROP_PIC_ORDER_CNT_TYPE, @@ -192,6 +269,26 @@ static const u32 sm8550_vdec_input_config_params[] = { HFI_PROP_SIGNAL_COLOR_INFO, }; +static const u32 sm8550_vdec_input_config_param_hevc[] = { + HFI_PROP_BITSTREAM_RESOLUTION, + HFI_PROP_CROP_OFFSETS, + HFI_PROP_LUMA_CHROMA_BIT_DEPTH, + HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT, + HFI_PROP_PROFILE, + HFI_PROP_LEVEL, + HFI_PROP_TIER, + HFI_PROP_SIGNAL_COLOR_INFO, +}; + +static const u32 sm8550_vdec_input_config_param_vp9[] = { + HFI_PROP_BITSTREAM_RESOLUTION, + HFI_PROP_CROP_OFFSETS, + HFI_PROP_LUMA_CHROMA_BIT_DEPTH, + HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT, + HFI_PROP_PROFILE, + HFI_PROP_LEVEL, +}; + static const u32 sm8550_vdec_output_config_params[] = { HFI_PROP_COLOR_FORMAT, HFI_PROP_LINEAR_STRIDE_SCANLINE, @@ -201,11 +298,19 @@ static const u32 sm8550_vdec_subscribe_input_properties[] = { HFI_PROP_NO_OUTPUT, }; -static const u32 sm8550_vdec_subscribe_output_properties[] = { +static const u32 sm8550_vdec_subscribe_output_properties_avc[] = { HFI_PROP_PICTURE_TYPE, HFI_PROP_CABAC_SESSION, }; +static const u32 sm8550_vdec_subscribe_output_properties_hevc[] = { + HFI_PROP_PICTURE_TYPE, +}; + +static const u32 sm8550_vdec_subscribe_output_properties_vp9[] = { + HFI_PROP_PICTURE_TYPE, +}; + static const u32 sm8550_dec_ip_int_buf_tbl[] = { BUF_BIN, BUF_COMV, @@ -248,19 +353,34 @@ struct iris_platform_data sm8550_data = { .ubwc_config = &ubwc_config_sm8550, .num_vpp_pipe = 4, .max_session_count = 16, - .max_core_mbpf = ((8192 * 4352) / 256) * 2, - .input_config_params = - sm8550_vdec_input_config_params, - .input_config_params_size = - ARRAY_SIZE(sm8550_vdec_input_config_params), + .max_core_mbpf = NUM_MBS_8K * 2, + .input_config_params_default = + sm8550_vdec_input_config_params_default, + .input_config_params_default_size = + ARRAY_SIZE(sm8550_vdec_input_config_params_default), + .input_config_params_hevc = + sm8550_vdec_input_config_param_hevc, + .input_config_params_hevc_size = + ARRAY_SIZE(sm8550_vdec_input_config_param_hevc), + .input_config_params_vp9 = + sm8550_vdec_input_config_param_vp9, + .input_config_params_vp9_size = + ARRAY_SIZE(sm8550_vdec_input_config_param_vp9), .output_config_params = sm8550_vdec_output_config_params, .output_config_params_size = ARRAY_SIZE(sm8550_vdec_output_config_params), .dec_input_prop = sm8550_vdec_subscribe_input_properties, .dec_input_prop_size = ARRAY_SIZE(sm8550_vdec_subscribe_input_properties), - .dec_output_prop = sm8550_vdec_subscribe_output_properties, - .dec_output_prop_size = ARRAY_SIZE(sm8550_vdec_subscribe_output_properties), + .dec_output_prop_avc = sm8550_vdec_subscribe_output_properties_avc, + .dec_output_prop_avc_size = + ARRAY_SIZE(sm8550_vdec_subscribe_output_properties_avc), + .dec_output_prop_hevc = sm8550_vdec_subscribe_output_properties_hevc, + .dec_output_prop_hevc_size = + ARRAY_SIZE(sm8550_vdec_subscribe_output_properties_hevc), + .dec_output_prop_vp9 = sm8550_vdec_subscribe_output_properties_vp9, + .dec_output_prop_vp9_size = + ARRAY_SIZE(sm8550_vdec_subscribe_output_properties_vp9), .dec_ip_int_buf_tbl = sm8550_dec_ip_int_buf_tbl, .dec_ip_int_buf_tbl_size = ARRAY_SIZE(sm8550_dec_ip_int_buf_tbl), @@ -308,19 +428,34 @@ struct iris_platform_data sm8650_data = { .ubwc_config = &ubwc_config_sm8550, .num_vpp_pipe = 4, .max_session_count = 16, - .max_core_mbpf = ((8192 * 4352) / 256) * 2, - .input_config_params = - sm8550_vdec_input_config_params, - .input_config_params_size = - ARRAY_SIZE(sm8550_vdec_input_config_params), + .max_core_mbpf = NUM_MBS_8K * 2, + .input_config_params_default = + sm8550_vdec_input_config_params_default, + .input_config_params_default_size = + ARRAY_SIZE(sm8550_vdec_input_config_params_default), + .input_config_params_hevc = + sm8550_vdec_input_config_param_hevc, + .input_config_params_hevc_size = + ARRAY_SIZE(sm8550_vdec_input_config_param_hevc), + .input_config_params_vp9 = + sm8550_vdec_input_config_param_vp9, + .input_config_params_vp9_size = + ARRAY_SIZE(sm8550_vdec_input_config_param_vp9), .output_config_params = sm8550_vdec_output_config_params, .output_config_params_size = ARRAY_SIZE(sm8550_vdec_output_config_params), .dec_input_prop = sm8550_vdec_subscribe_input_properties, .dec_input_prop_size = ARRAY_SIZE(sm8550_vdec_subscribe_input_properties), - .dec_output_prop = sm8550_vdec_subscribe_output_properties, - .dec_output_prop_size = ARRAY_SIZE(sm8550_vdec_subscribe_output_properties), + .dec_output_prop_avc = sm8550_vdec_subscribe_output_properties_avc, + .dec_output_prop_avc_size = + ARRAY_SIZE(sm8550_vdec_subscribe_output_properties_avc), + .dec_output_prop_hevc = sm8550_vdec_subscribe_output_properties_hevc, + .dec_output_prop_hevc_size = + ARRAY_SIZE(sm8550_vdec_subscribe_output_properties_hevc), + .dec_output_prop_vp9 = sm8550_vdec_subscribe_output_properties_vp9, + .dec_output_prop_vp9_size = + ARRAY_SIZE(sm8550_vdec_subscribe_output_properties_vp9), .dec_ip_int_buf_tbl = sm8550_dec_ip_int_buf_tbl, .dec_ip_int_buf_tbl_size = ARRAY_SIZE(sm8550_dec_ip_int_buf_tbl), @@ -365,18 +500,33 @@ struct iris_platform_data qcs8300_data = { .num_vpp_pipe = 2, .max_session_count = 16, .max_core_mbpf = ((4096 * 2176) / 256) * 4, - .input_config_params = - sm8550_vdec_input_config_params, - .input_config_params_size = - ARRAY_SIZE(sm8550_vdec_input_config_params), + .input_config_params_default = + sm8550_vdec_input_config_params_default, + .input_config_params_default_size = + ARRAY_SIZE(sm8550_vdec_input_config_params_default), + .input_config_params_hevc = + sm8550_vdec_input_config_param_hevc, + .input_config_params_hevc_size = + ARRAY_SIZE(sm8550_vdec_input_config_param_hevc), + .input_config_params_vp9 = + sm8550_vdec_input_config_param_vp9, + .input_config_params_vp9_size = + ARRAY_SIZE(sm8550_vdec_input_config_param_vp9), .output_config_params = sm8550_vdec_output_config_params, .output_config_params_size = ARRAY_SIZE(sm8550_vdec_output_config_params), .dec_input_prop = sm8550_vdec_subscribe_input_properties, .dec_input_prop_size = ARRAY_SIZE(sm8550_vdec_subscribe_input_properties), - .dec_output_prop = sm8550_vdec_subscribe_output_properties, - .dec_output_prop_size = ARRAY_SIZE(sm8550_vdec_subscribe_output_properties), + .dec_output_prop_avc = sm8550_vdec_subscribe_output_properties_avc, + .dec_output_prop_avc_size = + ARRAY_SIZE(sm8550_vdec_subscribe_output_properties_avc), + .dec_output_prop_hevc = sm8550_vdec_subscribe_output_properties_hevc, + .dec_output_prop_hevc_size = + ARRAY_SIZE(sm8550_vdec_subscribe_output_properties_hevc), + .dec_output_prop_vp9 = sm8550_vdec_subscribe_output_properties_vp9, + .dec_output_prop_vp9_size = + ARRAY_SIZE(sm8550_vdec_subscribe_output_properties_vp9), .dec_ip_int_buf_tbl = sm8550_dec_ip_int_buf_tbl, .dec_ip_int_buf_tbl_size = ARRAY_SIZE(sm8550_dec_ip_int_buf_tbl), diff --git a/drivers/media/platform/qcom/iris/iris_platform_qcs8300.h b/drivers/media/platform/qcom/iris/iris_platform_qcs8300.h index f82355d72fcff..a8d66ed388a34 100644 --- a/drivers/media/platform/qcom/iris/iris_platform_qcs8300.h +++ b/drivers/media/platform/qcom/iris/iris_platform_qcs8300.h @@ -5,48 +5,124 @@ static struct platform_inst_fw_cap inst_fw_cap_qcs8300[] = { { - .cap_id = PROFILE, + .cap_id = PROFILE_H264, .min = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE, .max = V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH, .step_or_mask = BIT(V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) | - BIT(V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH) | - BIT(V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE) | - BIT(V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) | - BIT(V4L2_MPEG_VIDEO_H264_PROFILE_HIGH), + BIT(V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE) | + BIT(V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) | + BIT(V4L2_MPEG_VIDEO_H264_PROFILE_HIGH) | + BIT(V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH), .value = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH, .hfi_id = HFI_PROP_PROFILE, .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU, .set = iris_set_u32_enum, }, { - .cap_id = LEVEL, + .cap_id = PROFILE_HEVC, + .min = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN, + .max = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE, + .step_or_mask = BIT(V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN) | + BIT(V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE), + .value = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN, + .hfi_id = HFI_PROP_PROFILE, + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU, + .set = iris_set_u32_enum, + }, + { + .cap_id = PROFILE_VP9, + .min = V4L2_MPEG_VIDEO_VP9_PROFILE_0, + .max = V4L2_MPEG_VIDEO_VP9_PROFILE_2, + .step_or_mask = BIT(V4L2_MPEG_VIDEO_VP9_PROFILE_0) | + BIT(V4L2_MPEG_VIDEO_VP9_PROFILE_2), + .value = V4L2_MPEG_VIDEO_VP9_PROFILE_0, + .hfi_id = HFI_PROP_PROFILE, + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU, + .set = iris_set_u32_enum, + }, + { + .cap_id = LEVEL_H264, .min = V4L2_MPEG_VIDEO_H264_LEVEL_1_0, .max = V4L2_MPEG_VIDEO_H264_LEVEL_6_2, .step_or_mask = BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_0) | - BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1B) | - BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_1) | - BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_2) | - BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_3) | - BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_0) | - BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_1) | - BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_2) | - BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_0) | - BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_1) | - BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_2) | - BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_0) | - BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_1) | - BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_2) | - BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_0) | - BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_1) | - BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_2) | - BIT(V4L2_MPEG_VIDEO_H264_LEVEL_6_0) | - BIT(V4L2_MPEG_VIDEO_H264_LEVEL_6_1) | - BIT(V4L2_MPEG_VIDEO_H264_LEVEL_6_2), + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1B) | + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_1) | + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_2) | + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_3) | + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_0) | + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_1) | + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_2) | + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_0) | + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_1) | + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_2) | + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_0) | + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_1) | + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_2) | + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_0) | + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_1) | + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_2) | + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_6_0) | + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_6_1) | + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_6_2), .value = V4L2_MPEG_VIDEO_H264_LEVEL_6_1, .hfi_id = HFI_PROP_LEVEL, .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU, .set = iris_set_u32_enum, }, + { + .cap_id = LEVEL_HEVC, + .min = V4L2_MPEG_VIDEO_HEVC_LEVEL_1, + .max = V4L2_MPEG_VIDEO_HEVC_LEVEL_6_2, + .step_or_mask = BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_1) | + BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_2) | + BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_2_1) | + BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_3) | + BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_3_1) | + BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_4) | + BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_4_1) | + BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_5) | + BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_5_1) | + BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_5_2) | + BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_6) | + BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_6_1) | + BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_6_2), + .value = V4L2_MPEG_VIDEO_HEVC_LEVEL_6_1, + .hfi_id = HFI_PROP_LEVEL, + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU, + .set = iris_set_u32_enum, + }, + { + .cap_id = LEVEL_VP9, + .min = V4L2_MPEG_VIDEO_VP9_LEVEL_1_0, + .max = V4L2_MPEG_VIDEO_VP9_LEVEL_6_0, + .step_or_mask = BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_1_0) | + BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_1_1) | + BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_2_0) | + BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_2_1) | + BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_3_0) | + BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_3_1) | + BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_4_0) | + BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_4_1) | + BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_5_0) | + BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_5_1) | + BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_5_2) | + BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_6_0), + .value = V4L2_MPEG_VIDEO_VP9_LEVEL_6_0, + .hfi_id = HFI_PROP_LEVEL, + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU, + .set = iris_set_u32_enum, + }, + { + .cap_id = TIER, + .min = V4L2_MPEG_VIDEO_HEVC_TIER_MAIN, + .max = V4L2_MPEG_VIDEO_HEVC_TIER_HIGH, + .step_or_mask = BIT(V4L2_MPEG_VIDEO_HEVC_TIER_MAIN) | + BIT(V4L2_MPEG_VIDEO_HEVC_TIER_HIGH), + .value = V4L2_MPEG_VIDEO_HEVC_TIER_HIGH, + .hfi_id = HFI_PROP_TIER, + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU, + .set = iris_set_u32_enum, + }, { .cap_id = INPUT_BUF_HOST_MAX_COUNT, .min = DEFAULT_MAX_HOST_BUF_COUNT, diff --git a/drivers/media/platform/qcom/iris/iris_platform_sm8250.c b/drivers/media/platform/qcom/iris/iris_platform_sm8250.c index 5c86fd7b7b6fd..8d0816a67ae0b 100644 --- a/drivers/media/platform/qcom/iris/iris_platform_sm8250.c +++ b/drivers/media/platform/qcom/iris/iris_platform_sm8250.c @@ -30,15 +30,6 @@ static struct platform_inst_fw_cap inst_fw_cap_sm8250[] = { .hfi_id = HFI_PROPERTY_PARAM_WORK_MODE, .set = iris_set_stage, }, - { - .cap_id = DEBLOCK, - .min = 0, - .max = 1, - .step_or_mask = 1, - .value = 0, - .hfi_id = HFI_PROPERTY_CONFIG_VDEC_POST_LOOP_DEBLOCKER, - .set = iris_set_u32, - }, }; static struct platform_inst_caps platform_inst_cap_sm8250 = { @@ -136,10 +127,10 @@ struct iris_platform_data sm8250_data = { .hw_response_timeout = HW_RESPONSE_TIMEOUT_VALUE, .num_vpp_pipe = 4, .max_session_count = 16, - .max_core_mbpf = (8192 * 4352) / 256, - .input_config_params = + .max_core_mbpf = NUM_MBS_8K, + .input_config_params_default = sm8250_vdec_input_config_param_default, - .input_config_params_size = + .input_config_params_default_size = ARRAY_SIZE(sm8250_vdec_input_config_param_default), .dec_ip_int_buf_tbl = sm8250_dec_ip_int_buf_tbl, diff --git a/drivers/media/platform/qcom/iris/iris_state.c b/drivers/media/platform/qcom/iris/iris_state.c index 5976e926c83d1..104e1687ad39d 100644 --- a/drivers/media/platform/qcom/iris/iris_state.c +++ b/drivers/media/platform/qcom/iris/iris_state.c @@ -245,7 +245,7 @@ int iris_inst_sub_state_change_pause(struct iris_inst *inst, u32 plane) return iris_inst_change_sub_state(inst, 0, set_sub_state); } -static inline bool iris_drc_pending(struct iris_inst *inst) +bool iris_drc_pending(struct iris_inst *inst) { return inst->sub_state & IRIS_INST_SUB_DRC && inst->sub_state & IRIS_INST_SUB_DRC_LAST; diff --git a/drivers/media/platform/qcom/iris/iris_state.h b/drivers/media/platform/qcom/iris/iris_state.h index 78c61aac5e7e0..e718386dbe040 100644 --- a/drivers/media/platform/qcom/iris/iris_state.h +++ b/drivers/media/platform/qcom/iris/iris_state.h @@ -140,5 +140,6 @@ int iris_inst_sub_state_change_drain_last(struct iris_inst *inst); int iris_inst_sub_state_change_drc_last(struct iris_inst *inst); int iris_inst_sub_state_change_pause(struct iris_inst *inst, u32 plane); bool iris_allow_cmd(struct iris_inst *inst, u32 cmd); +bool iris_drc_pending(struct iris_inst *inst); #endif diff --git a/drivers/media/platform/qcom/iris/iris_vb2.c b/drivers/media/platform/qcom/iris/iris_vb2.c index cdf11feb590b5..8b17c7c394879 100644 --- a/drivers/media/platform/qcom/iris/iris_vb2.c +++ b/drivers/media/platform/qcom/iris/iris_vb2.c @@ -259,13 +259,14 @@ int iris_vb2_buf_prepare(struct vb2_buffer *vb) return -EINVAL; } - if (vb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE && - vb2_plane_size(vb, 0) < iris_get_buffer_size(inst, BUF_OUTPUT)) - return -EINVAL; - if (vb->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE && - vb2_plane_size(vb, 0) < iris_get_buffer_size(inst, BUF_INPUT)) - return -EINVAL; - + if (!(inst->sub_state & IRIS_INST_SUB_DRC)) { + if (vb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE && + vb2_plane_size(vb, 0) < iris_get_buffer_size(inst, BUF_OUTPUT)) + return -EINVAL; + if (vb->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE && + vb2_plane_size(vb, 0) < iris_get_buffer_size(inst, BUF_INPUT)) + return -EINVAL; + } return 0; } @@ -304,7 +305,7 @@ void iris_vb2_buf_queue(struct vb2_buffer *vb2) goto exit; } - if (V4L2_TYPE_IS_CAPTURE(vb2->vb2_queue->type)) { + if (!inst->last_buffer_dequeued && V4L2_TYPE_IS_CAPTURE(vb2->vb2_queue->type)) { if ((inst->sub_state & IRIS_INST_SUB_DRC && inst->sub_state & IRIS_INST_SUB_DRC_LAST) || (inst->sub_state & IRIS_INST_SUB_DRAIN && @@ -318,6 +319,7 @@ void iris_vb2_buf_queue(struct vb2_buffer *vb2) v4l2_event_queue_fh(&inst->fh, &eos); v4l2_m2m_mark_stopped(m2m_ctx); } + inst->last_buffer_dequeued = true; goto exit; } } diff --git a/drivers/media/platform/qcom/iris/iris_vdec.c b/drivers/media/platform/qcom/iris/iris_vdec.c index 4143acedfc574..d670b51c5839d 100644 --- a/drivers/media/platform/qcom/iris/iris_vdec.c +++ b/drivers/media/platform/qcom/iris/iris_vdec.c @@ -32,6 +32,7 @@ int iris_vdec_inst_init(struct iris_inst *inst) f->fmt.pix_mp.width = DEFAULT_WIDTH; f->fmt.pix_mp.height = DEFAULT_HEIGHT; f->fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H264; + inst->codec = f->fmt.pix_mp.pixelformat; f->fmt.pix_mp.num_planes = 1; f->fmt.pix_mp.plane_fmt[0].bytesperline = 0; f->fmt.pix_mp.plane_fmt[0].sizeimage = iris_get_buffer_size(inst, BUF_INPUT); @@ -67,14 +68,67 @@ void iris_vdec_inst_deinit(struct iris_inst *inst) kfree(inst->fmt_src); } +static const struct iris_fmt iris_vdec_formats[] = { + [IRIS_FMT_H264] = { + .pixfmt = V4L2_PIX_FMT_H264, + .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, + }, + [IRIS_FMT_HEVC] = { + .pixfmt = V4L2_PIX_FMT_HEVC, + .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, + }, + [IRIS_FMT_VP9] = { + .pixfmt = V4L2_PIX_FMT_VP9, + .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, + }, +}; + +static const struct iris_fmt * +find_format(struct iris_inst *inst, u32 pixfmt, u32 type) +{ + unsigned int size = ARRAY_SIZE(iris_vdec_formats); + const struct iris_fmt *fmt = iris_vdec_formats; + unsigned int i; + + for (i = 0; i < size; i++) { + if (fmt[i].pixfmt == pixfmt) + break; + } + + if (i == size || fmt[i].type != type) + return NULL; + + return &fmt[i]; +} + +static const struct iris_fmt * +find_format_by_index(struct iris_inst *inst, u32 index, u32 type) +{ + const struct iris_fmt *fmt = iris_vdec_formats; + unsigned int size = ARRAY_SIZE(iris_vdec_formats); + + if (index >= size || fmt[index].type != type) + return NULL; + + return &fmt[index]; +} + int iris_vdec_enum_fmt(struct iris_inst *inst, struct v4l2_fmtdesc *f) { + const struct iris_fmt *fmt; + switch (f->type) { case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: - f->pixelformat = V4L2_PIX_FMT_H264; + fmt = find_format_by_index(inst, f->index, f->type); + if (!fmt) + return -EINVAL; + + f->pixelformat = fmt->pixfmt; f->flags = V4L2_FMT_FLAG_COMPRESSED | V4L2_FMT_FLAG_DYN_RESOLUTION; break; case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: + if (f->index) + return -EINVAL; f->pixelformat = V4L2_PIX_FMT_NV12; break; default: @@ -88,13 +142,15 @@ int iris_vdec_try_fmt(struct iris_inst *inst, struct v4l2_format *f) { struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp; struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx; + const struct iris_fmt *fmt; struct v4l2_format *f_inst; struct vb2_queue *src_q; memset(pixmp->reserved, 0, sizeof(pixmp->reserved)); + fmt = find_format(inst, pixmp->pixelformat, f->type); switch (f->type) { case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: - if (f->fmt.pix_mp.pixelformat != V4L2_PIX_FMT_H264) { + if (!fmt) { f_inst = inst->fmt_src; f->fmt.pix_mp.width = f_inst->fmt.pix_mp.width; f->fmt.pix_mp.height = f_inst->fmt.pix_mp.height; @@ -102,7 +158,7 @@ int iris_vdec_try_fmt(struct iris_inst *inst, struct v4l2_format *f) } break; case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: - if (f->fmt.pix_mp.pixelformat != V4L2_PIX_FMT_NV12) { + if (!fmt) { f_inst = inst->fmt_dst; f->fmt.pix_mp.pixelformat = f_inst->fmt.pix_mp.pixelformat; f->fmt.pix_mp.width = f_inst->fmt.pix_mp.width; @@ -145,13 +201,14 @@ int iris_vdec_s_fmt(struct iris_inst *inst, struct v4l2_format *f) switch (f->type) { case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: - if (f->fmt.pix_mp.pixelformat != V4L2_PIX_FMT_H264) + if (!(find_format(inst, f->fmt.pix_mp.pixelformat, f->type))) return -EINVAL; fmt = inst->fmt_src; fmt->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - - codec_align = DEFAULT_CODEC_ALIGNMENT; + fmt->fmt.pix_mp.pixelformat = f->fmt.pix_mp.pixelformat; + inst->codec = fmt->fmt.pix_mp.pixelformat; + codec_align = inst->codec == V4L2_PIX_FMT_HEVC ? 32 : 16; fmt->fmt.pix_mp.width = ALIGN(f->fmt.pix_mp.width, codec_align); fmt->fmt.pix_mp.height = ALIGN(f->fmt.pix_mp.height, codec_align); fmt->fmt.pix_mp.num_planes = 1; @@ -171,6 +228,11 @@ int iris_vdec_s_fmt(struct iris_inst *inst, struct v4l2_format *f) output_fmt->fmt.pix_mp.ycbcr_enc = f->fmt.pix_mp.ycbcr_enc; output_fmt->fmt.pix_mp.quantization = f->fmt.pix_mp.quantization; + /* Update capture format based on new ip w/h */ + output_fmt->fmt.pix_mp.width = ALIGN(f->fmt.pix_mp.width, 128); + output_fmt->fmt.pix_mp.height = ALIGN(f->fmt.pix_mp.height, 32); + inst->buffers[BUF_OUTPUT].size = iris_get_buffer_size(inst, BUF_OUTPUT); + inst->crop.left = 0; inst->crop.top = 0; inst->crop.width = f->fmt.pix_mp.width; @@ -239,35 +301,6 @@ void iris_vdec_src_change(struct iris_inst *inst) v4l2_event_queue_fh(&inst->fh, &event); } -static int iris_vdec_get_num_queued_buffers(struct iris_inst *inst, - enum iris_buffer_type type) -{ - struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx; - struct v4l2_m2m_buffer *buffer, *n; - struct iris_buffer *buf; - u32 count = 0; - - switch (type) { - case BUF_INPUT: - v4l2_m2m_for_each_src_buf_safe(m2m_ctx, buffer, n) { - buf = to_iris_buffer(&buffer->vb); - if (!(buf->attr & BUF_ATTR_QUEUED)) - continue; - count++; - } - return count; - case BUF_OUTPUT: - v4l2_m2m_for_each_dst_buf_safe(m2m_ctx, buffer, n) { - buf = to_iris_buffer(&buffer->vb); - if (!(buf->attr & BUF_ATTR_QUEUED)) - continue; - count++; - } - return count; - default: - return count; - } -} static void iris_vdec_flush_deferred_buffers(struct iris_inst *inst, enum iris_buffer_type type) @@ -316,7 +349,6 @@ int iris_vdec_session_streamoff(struct iris_inst *inst, u32 plane) { const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; enum iris_buffer_type buffer_type; - u32 count; int ret; switch (plane) { @@ -334,12 +366,6 @@ int iris_vdec_session_streamoff(struct iris_inst *inst, u32 plane) if (ret) goto error; - count = iris_vdec_get_num_queued_buffers(inst, buffer_type); - if (count) { - ret = -EINVAL; - goto error; - } - ret = iris_inst_state_change_streamoff(inst, plane); if (ret) goto error; @@ -408,7 +434,7 @@ int iris_vdec_streamon_input(struct iris_inst *inst) iris_get_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); - ret = iris_destroy_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); + ret = iris_destroy_dequeued_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); if (ret) return ret; @@ -482,6 +508,8 @@ static int iris_vdec_process_streamon_output(struct iris_inst *inst) if (ret) return ret; + inst->last_buffer_dequeued = false; + return iris_inst_change_sub_state(inst, clear_sub_state, 0); } @@ -496,7 +524,7 @@ int iris_vdec_streamon_output(struct iris_inst *inst) iris_get_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); - ret = iris_destroy_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); + ret = iris_destroy_dequeued_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); if (ret) return ret; diff --git a/drivers/media/platform/qcom/iris/iris_vdec.h b/drivers/media/platform/qcom/iris/iris_vdec.h index b24932dc511a6..cd7aab66dc7c8 100644 --- a/drivers/media/platform/qcom/iris/iris_vdec.h +++ b/drivers/media/platform/qcom/iris/iris_vdec.h @@ -8,6 +8,17 @@ struct iris_inst; +enum iris_fmt_type { + IRIS_FMT_H264, + IRIS_FMT_HEVC, + IRIS_FMT_VP9, +}; + +struct iris_fmt { + u32 pixfmt; + u32 type; +}; + int iris_vdec_inst_init(struct iris_inst *inst); void iris_vdec_inst_deinit(struct iris_inst *inst); int iris_vdec_enum_fmt(struct iris_inst *inst, struct v4l2_fmtdesc *f); diff --git a/drivers/media/platform/qcom/iris/iris_vidc.c b/drivers/media/platform/qcom/iris/iris_vidc.c index ca0f4e310f77f..c417e8c31f806 100644 --- a/drivers/media/platform/qcom/iris/iris_vidc.c +++ b/drivers/media/platform/qcom/iris/iris_vidc.c @@ -221,6 +221,33 @@ static void iris_session_close(struct iris_inst *inst) iris_wait_for_session_response(inst, false); } +static void iris_check_num_queued_internal_buffers(struct iris_inst *inst, u32 plane) +{ + const struct iris_platform_data *platform_data = inst->core->iris_platform_data; + struct iris_buffer *buf, *next; + struct iris_buffers *buffers; + const u32 *internal_buf_type; + u32 internal_buffer_count, i; + u32 count = 0; + + if (V4L2_TYPE_IS_OUTPUT(plane)) { + internal_buf_type = platform_data->dec_ip_int_buf_tbl; + internal_buffer_count = platform_data->dec_ip_int_buf_tbl_size; + } else { + internal_buf_type = platform_data->dec_op_int_buf_tbl; + internal_buffer_count = platform_data->dec_op_int_buf_tbl_size; + } + + for (i = 0; i < internal_buffer_count; i++) { + buffers = &inst->buffers[internal_buf_type[i]]; + list_for_each_entry_safe(buf, next, &buffers->list, list) + count++; + if (count) + dev_err(inst->core->dev, "%d buffer of type %d not released", + count, internal_buf_type[i]); + } +} + int iris_close(struct file *filp) { struct iris_inst *inst = iris_get_inst(filp, NULL); @@ -233,8 +260,10 @@ int iris_close(struct file *filp) iris_session_close(inst); iris_inst_change_state(inst, IRIS_INST_DEINIT); iris_v4l2_fh_deinit(inst); - iris_destroy_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); - iris_destroy_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); + iris_destroy_all_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); + iris_destroy_all_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); + iris_check_num_queued_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); + iris_check_num_queued_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); iris_remove_session(inst); mutex_unlock(&inst->lock); mutex_destroy(&inst->ctx_q_lock); @@ -249,9 +278,6 @@ static int iris_enum_fmt(struct file *filp, void *fh, struct v4l2_fmtdesc *f) { struct iris_inst *inst = iris_get_inst(filp, NULL); - if (f->index) - return -EINVAL; - return iris_vdec_enum_fmt(inst, f); } diff --git a/drivers/media/platform/qcom/iris/iris_vpu_buffer.c b/drivers/media/platform/qcom/iris/iris_vpu_buffer.c index dce25e410d80b..13ee93356bcb0 100644 --- a/drivers/media/platform/qcom/iris/iris_vpu_buffer.c +++ b/drivers/media/platform/qcom/iris/iris_vpu_buffer.c @@ -31,6 +31,42 @@ static u32 hfi_buffer_bin_h264d(u32 frame_width, u32 frame_height, u32 num_vpp_p return size_h264d_hw_bin_buffer(n_aligned_w, n_aligned_h, num_vpp_pipes); } +static u32 size_h265d_hw_bin_buffer(u32 frame_width, u32 frame_height, u32 num_vpp_pipes) +{ + u32 product = frame_width * frame_height; + u32 size_yuv, size_bin_hdr, size_bin_res; + + size_yuv = (product <= BIN_BUFFER_THRESHOLD) ? + ((BIN_BUFFER_THRESHOLD * 3) >> 1) : ((product * 3) >> 1); + size_bin_hdr = size_yuv * H265_CABAC_HDR_RATIO_HD_TOT; + size_bin_res = size_yuv * H265_CABAC_RES_RATIO_HD_TOT; + size_bin_hdr = ALIGN(size_bin_hdr / num_vpp_pipes, DMA_ALIGNMENT) * num_vpp_pipes; + size_bin_res = ALIGN(size_bin_res / num_vpp_pipes, DMA_ALIGNMENT) * num_vpp_pipes; + + return size_bin_hdr + size_bin_res; +} + +static u32 hfi_buffer_bin_vp9d(u32 frame_width, u32 frame_height, u32 num_vpp_pipes) +{ + u32 _size_yuv = ALIGN(frame_width, 16) * ALIGN(frame_height, 16) * 3 / 2; + u32 _size = ALIGN(((max_t(u32, _size_yuv, ((BIN_BUFFER_THRESHOLD * 3) >> 1)) * + VPX_DECODER_FRAME_BIN_HDR_BUDGET / VPX_DECODER_FRAME_BIN_DENOMINATOR * + VPX_DECODER_FRAME_CONCURENCY_LVL) / num_vpp_pipes), DMA_ALIGNMENT) + + ALIGN(((max_t(u32, _size_yuv, ((BIN_BUFFER_THRESHOLD * 3) >> 1)) * + VPX_DECODER_FRAME_BIN_RES_BUDGET / VPX_DECODER_FRAME_BIN_DENOMINATOR * + VPX_DECODER_FRAME_CONCURENCY_LVL) / num_vpp_pipes), DMA_ALIGNMENT); + + return _size * num_vpp_pipes; +} + +static u32 hfi_buffer_bin_h265d(u32 frame_width, u32 frame_height, u32 num_vpp_pipes) +{ + u32 n_aligned_w = ALIGN(frame_width, 16); + u32 n_aligned_h = ALIGN(frame_height, 16); + + return size_h265d_hw_bin_buffer(n_aligned_w, n_aligned_h, num_vpp_pipes); +} + static u32 hfi_buffer_comv_h264d(u32 frame_width, u32 frame_height, u32 _comv_bufcount) { u32 frame_height_in_mbs = DIV_ROUND_UP(frame_height, 16); @@ -55,6 +91,17 @@ static u32 hfi_buffer_comv_h264d(u32 frame_width, u32 frame_height, u32 _comv_bu return (size_colloc * (_comv_bufcount)) + 512; } +static u32 hfi_buffer_comv_h265d(u32 frame_width, u32 frame_height, u32 _comv_bufcount) +{ + u32 frame_height_in_mbs = (frame_height + 15) >> 4; + u32 frame_width_in_mbs = (frame_width + 15) >> 4; + u32 _size; + + _size = ALIGN(((frame_width_in_mbs * frame_height_in_mbs) << 8), 512); + + return (_size * (_comv_bufcount)) + 512; +} + static u32 size_h264d_bse_cmd_buf(u32 frame_height) { u32 height = ALIGN(frame_height, 32); @@ -63,6 +110,44 @@ static u32 size_h264d_bse_cmd_buf(u32 frame_height) SIZE_H264D_BSE_CMD_PER_BUF; } +static u32 size_h265d_bse_cmd_buf(u32 frame_width, u32 frame_height) +{ + u32 _size = ALIGN(((ALIGN(frame_width, LCU_MAX_SIZE_PELS) / LCU_MIN_SIZE_PELS) * + (ALIGN(frame_height, LCU_MAX_SIZE_PELS) / LCU_MIN_SIZE_PELS)) * + NUM_HW_PIC_BUF, DMA_ALIGNMENT); + _size = min_t(u32, _size, H265D_MAX_SLICE + 1); + _size = 2 * _size * SIZE_H265D_BSE_CMD_PER_BUF; + + return _size; +} + +static u32 hfi_buffer_persist_h265d(u32 rpu_enabled) +{ + return ALIGN((SIZE_SLIST_BUF_H265 * NUM_SLIST_BUF_H265 + + H265_NUM_FRM_INFO * H265_DISPLAY_BUF_SIZE + + H265_NUM_TILE * sizeof(u32) + + NUM_HW_PIC_BUF * SIZE_SEI_USERDATA + + rpu_enabled * NUM_HW_PIC_BUF * SIZE_DOLBY_RPU_METADATA), + DMA_ALIGNMENT); +} + +static inline +u32 hfi_iris3_vp9d_comv_size(void) +{ + return (((8192 + 63) >> 6) * ((4320 + 63) >> 6) * 8 * 8 * 2 * 8); +} + +static u32 hfi_buffer_persist_vp9d(void) +{ + return ALIGN(VP9_NUM_PROBABILITY_TABLE_BUF * VP9_PROB_TABLE_SIZE, DMA_ALIGNMENT) + + ALIGN(hfi_iris3_vp9d_comv_size(), DMA_ALIGNMENT) + + ALIGN(MAX_SUPERFRAME_HEADER_LEN, DMA_ALIGNMENT) + + ALIGN(VP9_UDC_HEADER_BUF_SIZE, DMA_ALIGNMENT) + + ALIGN(VP9_NUM_FRAME_INFO_BUF * CCE_TILE_OFFSET_SIZE, DMA_ALIGNMENT) + + ALIGN(VP9_NUM_FRAME_INFO_BUF * VP9_FRAME_INFO_BUF_SIZE, DMA_ALIGNMENT) + + HDR10_HIST_EXTRADATA_SIZE; +} + static u32 size_h264d_vpp_cmd_buf(u32 frame_height) { u32 size, height = ALIGN(frame_height, 32); @@ -83,17 +168,45 @@ static u32 hfi_buffer_persist_h264d(void) static u32 hfi_buffer_non_comv_h264d(u32 frame_width, u32 frame_height, u32 num_vpp_pipes) { - u32 size_bse, size_vpp, size; - - size_bse = size_h264d_bse_cmd_buf(frame_height); - size_vpp = size_h264d_vpp_cmd_buf(frame_height); - size = ALIGN(size_bse, DMA_ALIGNMENT) + + u32 size_bse = size_h264d_bse_cmd_buf(frame_height); + u32 size_vpp = size_h264d_vpp_cmd_buf(frame_height); + u32 size = ALIGN(size_bse, DMA_ALIGNMENT) + ALIGN(size_vpp, DMA_ALIGNMENT) + ALIGN(SIZE_HW_PIC(SIZE_H264D_HW_PIC_T), DMA_ALIGNMENT); return ALIGN(size, DMA_ALIGNMENT); } +static u32 size_h265d_vpp_cmd_buf(u32 frame_width, u32 frame_height) +{ + u32 _size = ALIGN(((ALIGN(frame_width, LCU_MAX_SIZE_PELS) / LCU_MIN_SIZE_PELS) * + (ALIGN(frame_height, LCU_MAX_SIZE_PELS) / LCU_MIN_SIZE_PELS)) * + NUM_HW_PIC_BUF, DMA_ALIGNMENT); + _size = min_t(u32, _size, H265D_MAX_SLICE + 1); + _size = ALIGN(_size, 4); + _size = 2 * _size * SIZE_H265D_VPP_CMD_PER_BUF; + if (_size > VPP_CMD_MAX_SIZE) + _size = VPP_CMD_MAX_SIZE; + + return _size; +} + +static u32 hfi_buffer_non_comv_h265d(u32 frame_width, u32 frame_height, u32 num_vpp_pipes) +{ + u32 _size_bse = size_h265d_bse_cmd_buf(frame_width, frame_height); + u32 _size_vpp = size_h265d_vpp_cmd_buf(frame_width, frame_height); + u32 _size = ALIGN(_size_bse, DMA_ALIGNMENT) + + ALIGN(_size_vpp, DMA_ALIGNMENT) + + ALIGN(NUM_HW_PIC_BUF * 20 * 22 * 4, DMA_ALIGNMENT) + + ALIGN(2 * sizeof(u16) * + (ALIGN(frame_width, LCU_MAX_SIZE_PELS) / LCU_MIN_SIZE_PELS) * + (ALIGN(frame_height, LCU_MAX_SIZE_PELS) / LCU_MIN_SIZE_PELS), DMA_ALIGNMENT) + + ALIGN(SIZE_HW_PIC(SIZE_H265D_HW_PIC_T), DMA_ALIGNMENT) + + HDR10_HIST_EXTRADATA_SIZE; + + return ALIGN(_size, DMA_ALIGNMENT); +} + static u32 size_vpss_lb(u32 frame_width, u32 frame_height) { u32 opb_lb_wr_llb_y_buffer_size, opb_lb_wr_llb_uv_buffer_size; @@ -119,6 +232,203 @@ static u32 size_vpss_lb(u32 frame_width, u32 frame_height) opb_lb_wr_llb_y_buffer_size; } +static inline +u32 size_h265d_lb_fe_top_data(u32 frame_width, u32 frame_height) +{ + return MAX_FE_NBR_DATA_LUMA_LINE_BUFFER_SIZE * + (ALIGN(frame_width, 64) + 8) * 2; +} + +static inline +u32 size_h265d_lb_fe_top_ctrl(u32 frame_width, u32 frame_height) +{ + return MAX_FE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE * + (ALIGN(frame_width, LCU_MAX_SIZE_PELS) / LCU_MIN_SIZE_PELS); +} + +static inline +u32 size_h265d_lb_fe_left_ctrl(u32 frame_width, u32 frame_height) +{ + return MAX_FE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE * + (ALIGN(frame_height, LCU_MAX_SIZE_PELS) / LCU_MIN_SIZE_PELS); +} + +static inline +u32 size_h265d_lb_se_top_ctrl(u32 frame_width, u32 frame_height) +{ + return (LCU_MAX_SIZE_PELS / 8 * (128 / 8)) * ((frame_width + 15) >> 4); +} + +static inline +u32 size_h265d_lb_se_left_ctrl(u32 frame_width, u32 frame_height) +{ + return max_t(u32, ((frame_height + 16 - 1) / 8) * + MAX_SE_NBR_CTRL_LCU16_LINE_BUFFER_SIZE, + max_t(u32, ((frame_height + 32 - 1) / 8) * + MAX_SE_NBR_CTRL_LCU32_LINE_BUFFER_SIZE, + ((frame_height + 64 - 1) / 8) * + MAX_SE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE)); +} + +static inline +u32 size_h265d_lb_pe_top_data(u32 frame_width, u32 frame_height) +{ + return MAX_PE_NBR_DATA_LCU64_LINE_BUFFER_SIZE * + (ALIGN(frame_width, LCU_MIN_SIZE_PELS) / LCU_MIN_SIZE_PELS); +} + +static inline +u32 size_h265d_lb_vsp_top(u32 frame_width, u32 frame_height) +{ + return ((frame_width + 63) >> 6) * 128; +} + +static inline +u32 size_h265d_lb_vsp_left(u32 frame_width, u32 frame_height) +{ + return ((frame_height + 63) >> 6) * 128; +} + +static inline +u32 size_h265d_lb_recon_dma_metadata_wr(u32 frame_width, u32 frame_height) +{ + return size_h264d_lb_recon_dma_metadata_wr(frame_height); +} + +static inline +u32 size_h265d_qp(u32 frame_width, u32 frame_height) +{ + return size_h264d_qp(frame_width, frame_height); +} + +static inline +u32 hfi_buffer_line_h265d(u32 frame_width, u32 frame_height, bool is_opb, u32 num_vpp_pipes) +{ + u32 vpss_lb_size = 0, _size; + + _size = ALIGN(size_h265d_lb_fe_top_data(frame_width, frame_height), DMA_ALIGNMENT) + + ALIGN(size_h265d_lb_fe_top_ctrl(frame_width, frame_height), DMA_ALIGNMENT) + + ALIGN(size_h265d_lb_fe_left_ctrl(frame_width, frame_height), + DMA_ALIGNMENT) * num_vpp_pipes + + ALIGN(size_h265d_lb_se_left_ctrl(frame_width, frame_height), + DMA_ALIGNMENT) * num_vpp_pipes + + ALIGN(size_h265d_lb_se_top_ctrl(frame_width, frame_height), DMA_ALIGNMENT) + + ALIGN(size_h265d_lb_pe_top_data(frame_width, frame_height), DMA_ALIGNMENT) + + ALIGN(size_h265d_lb_vsp_top(frame_width, frame_height), DMA_ALIGNMENT) + + ALIGN(size_h265d_lb_vsp_left(frame_width, frame_height), + DMA_ALIGNMENT) * num_vpp_pipes + + ALIGN(size_h265d_lb_recon_dma_metadata_wr(frame_width, frame_height), + DMA_ALIGNMENT) * 4 + + ALIGN(size_h265d_qp(frame_width, frame_height), DMA_ALIGNMENT); + if (is_opb) + vpss_lb_size = size_vpss_lb(frame_width, frame_height); + + return ALIGN((_size + vpss_lb_size), DMA_ALIGNMENT); +} + +static inline +u32 size_vpxd_lb_fe_left_ctrl(u32 frame_width, u32 frame_height) +{ + return max_t(u32, ((frame_height + 15) >> 4) * + MAX_FE_NBR_CTRL_LCU16_LINE_BUFFER_SIZE, + max_t(u32, ((frame_height + 31) >> 5) * + MAX_FE_NBR_CTRL_LCU32_LINE_BUFFER_SIZE, + ((frame_height + 63) >> 6) * + MAX_FE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE)); +} + +static inline +u32 size_vpxd_lb_fe_top_ctrl(u32 frame_width, u32 frame_height) +{ + return ((ALIGN(frame_width, 64) + 8) * 10 * 2); +} + +static inline +u32 size_vpxd_lb_se_top_ctrl(u32 frame_width, u32 frame_height) +{ + return ((frame_width + 15) >> 4) * MAX_FE_NBR_CTRL_LCU16_LINE_BUFFER_SIZE; +} + +static inline +u32 size_vpxd_lb_se_left_ctrl(u32 frame_width, u32 frame_height) +{ + return max_t(u32, ((frame_height + 15) >> 4) * + MAX_SE_NBR_CTRL_LCU16_LINE_BUFFER_SIZE, + max_t(u32, ((frame_height + 31) >> 5) * + MAX_SE_NBR_CTRL_LCU32_LINE_BUFFER_SIZE, + ((frame_height + 63) >> 6) * + MAX_SE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE)); +} + +static inline +u32 size_vpxd_lb_recon_dma_metadata_wr(u32 frame_width, u32 frame_height) +{ + return ALIGN((ALIGN(frame_height, 8) / (4 / 2)) * 64, + BUFFER_ALIGNMENT_32_BYTES); +} + +static inline +u32 size_mp2d_lb_fe_top_data(u32 frame_width, u32 frame_height) +{ + return ((ALIGN(frame_width, 16) + 8) * 10 * 2); +} + +static inline +u32 size_vp9d_lb_fe_top_data(u32 frame_width, u32 frame_height) +{ + return (ALIGN(ALIGN(frame_width, 8), 64) + 8) * 10 * 2; +} + +static inline +u32 size_vp9d_lb_pe_top_data(u32 frame_width, u32 frame_height) +{ + return ((ALIGN(ALIGN(frame_width, 8), 64) >> 6) * 176); +} + +static inline +u32 size_vp9d_lb_vsp_top(u32 frame_width, u32 frame_height) +{ + return (((ALIGN(ALIGN(frame_width, 8), 64) >> 6) * 64 * 8) + 256); +} + +static inline +u32 size_vp9d_qp(u32 frame_width, u32 frame_height) +{ + return size_h264d_qp(frame_width, frame_height); +} + +static inline +u32 hfi_iris3_vp9d_lb_size(u32 frame_width, u32 frame_height, u32 num_vpp_pipes) +{ + return ALIGN(size_vpxd_lb_fe_left_ctrl(frame_width, frame_height), DMA_ALIGNMENT) * + num_vpp_pipes + + ALIGN(size_vpxd_lb_se_left_ctrl(frame_width, frame_height), DMA_ALIGNMENT) * + num_vpp_pipes + + ALIGN(size_vp9d_lb_vsp_top(frame_width, frame_height), DMA_ALIGNMENT) + + ALIGN(size_vpxd_lb_fe_top_ctrl(frame_width, frame_height), DMA_ALIGNMENT) + + 2 * ALIGN(size_vpxd_lb_recon_dma_metadata_wr(frame_width, frame_height), + DMA_ALIGNMENT) + + ALIGN(size_vpxd_lb_se_top_ctrl(frame_width, frame_height), DMA_ALIGNMENT) + + ALIGN(size_vp9d_lb_pe_top_data(frame_width, frame_height), DMA_ALIGNMENT) + + ALIGN(size_vp9d_lb_fe_top_data(frame_width, frame_height), DMA_ALIGNMENT) + + ALIGN(size_vp9d_qp(frame_width, frame_height), DMA_ALIGNMENT); +} + +static inline +u32 hfi_buffer_line_vp9d(u32 frame_width, u32 frame_height, u32 _yuv_bufcount_min, bool is_opb, + u32 num_vpp_pipes) +{ + u32 vpss_lb_size = 0; + u32 _lb_size; + + _lb_size = hfi_iris3_vp9d_lb_size(frame_width, frame_height, num_vpp_pipes); + + if (is_opb) + vpss_lb_size = size_vpss_lb(frame_width, frame_height); + + return _lb_size + vpss_lb_size + 4096; +} + static u32 hfi_buffer_line_h264d(u32 frame_width, u32 frame_height, bool is_opb, u32 num_vpp_pipes) { @@ -148,7 +458,14 @@ static u32 iris_vpu_dec_bin_size(struct iris_inst *inst) u32 height = f->fmt.pix_mp.height; u32 width = f->fmt.pix_mp.width; - return hfi_buffer_bin_h264d(width, height, num_vpp_pipes); + if (inst->codec == V4L2_PIX_FMT_H264) + return hfi_buffer_bin_h264d(width, height, num_vpp_pipes); + else if (inst->codec == V4L2_PIX_FMT_HEVC) + return hfi_buffer_bin_h265d(width, height, num_vpp_pipes); + else if (inst->codec == V4L2_PIX_FMT_VP9) + return hfi_buffer_bin_vp9d(width, height, num_vpp_pipes); + + return 0; } static u32 iris_vpu_dec_comv_size(struct iris_inst *inst) @@ -158,12 +475,24 @@ static u32 iris_vpu_dec_comv_size(struct iris_inst *inst) u32 height = f->fmt.pix_mp.height; u32 width = f->fmt.pix_mp.width; - return hfi_buffer_comv_h264d(width, height, num_comv); + if (inst->codec == V4L2_PIX_FMT_H264) + return hfi_buffer_comv_h264d(width, height, num_comv); + else if (inst->codec == V4L2_PIX_FMT_HEVC) + return hfi_buffer_comv_h265d(width, height, num_comv); + + return 0; } static u32 iris_vpu_dec_persist_size(struct iris_inst *inst) { - return hfi_buffer_persist_h264d(); + if (inst->codec == V4L2_PIX_FMT_H264) + return hfi_buffer_persist_h264d(); + else if (inst->codec == V4L2_PIX_FMT_HEVC) + return hfi_buffer_persist_h265d(0); + else if (inst->codec == V4L2_PIX_FMT_VP9) + return hfi_buffer_persist_vp9d(); + + return 0; } static u32 iris_vpu_dec_dpb_size(struct iris_inst *inst) @@ -181,7 +510,12 @@ static u32 iris_vpu_dec_non_comv_size(struct iris_inst *inst) u32 height = f->fmt.pix_mp.height; u32 width = f->fmt.pix_mp.width; - return hfi_buffer_non_comv_h264d(width, height, num_vpp_pipes); + if (inst->codec == V4L2_PIX_FMT_H264) + return hfi_buffer_non_comv_h264d(width, height, num_vpp_pipes); + else if (inst->codec == V4L2_PIX_FMT_HEVC) + return hfi_buffer_non_comv_h265d(width, height, num_vpp_pipes); + + return 0; } static u32 iris_vpu_dec_line_size(struct iris_inst *inst) @@ -191,11 +525,20 @@ static u32 iris_vpu_dec_line_size(struct iris_inst *inst) u32 height = f->fmt.pix_mp.height; u32 width = f->fmt.pix_mp.width; bool is_opb = false; + u32 out_min_count = inst->buffers[BUF_OUTPUT].min_count; if (iris_split_mode_enabled(inst)) is_opb = true; - return hfi_buffer_line_h264d(width, height, is_opb, num_vpp_pipes); + if (inst->codec == V4L2_PIX_FMT_H264) + return hfi_buffer_line_h264d(width, height, is_opb, num_vpp_pipes); + else if (inst->codec == V4L2_PIX_FMT_HEVC) + return hfi_buffer_line_h265d(width, height, is_opb, num_vpp_pipes); + else if (inst->codec == V4L2_PIX_FMT_VP9) + return hfi_buffer_line_vp9d(width, height, out_min_count, is_opb, + num_vpp_pipes); + + return 0; } static u32 iris_vpu_dec_scratch1_size(struct iris_inst *inst) @@ -205,6 +548,24 @@ static u32 iris_vpu_dec_scratch1_size(struct iris_inst *inst) iris_vpu_dec_line_size(inst); } +static int output_min_count(struct iris_inst *inst) +{ + int output_min_count = 4; + + /* fw_min_count > 0 indicates reconfig event has already arrived */ + if (inst->fw_min_count) { + if (iris_split_mode_enabled(inst) && inst->codec == V4L2_PIX_FMT_VP9) + return min_t(u32, 4, inst->fw_min_count); + else + return inst->fw_min_count; + } + + if (inst->codec == V4L2_PIX_FMT_VP9) + output_min_count = 9; + + return output_min_count; +} + struct iris_vpu_buf_type_handle { enum iris_buffer_type type; u32 (*handle)(struct iris_inst *inst); @@ -238,6 +599,19 @@ int iris_vpu_buf_size(struct iris_inst *inst, enum iris_buffer_type buffer_type) return size; } +static u32 internal_buffer_count(struct iris_inst *inst, + enum iris_buffer_type buffer_type) +{ + if (buffer_type == BUF_BIN || buffer_type == BUF_LINE || + buffer_type == BUF_PERSIST) { + return 1; + } else if (buffer_type == BUF_COMV || buffer_type == BUF_NON_COMV) { + if (inst->codec == V4L2_PIX_FMT_H264 || inst->codec == V4L2_PIX_FMT_HEVC) + return 1; + } + return 0; +} + static inline int iris_vpu_dpb_count(struct iris_inst *inst) { if (iris_split_mode_enabled(inst)) { @@ -254,12 +628,13 @@ int iris_vpu_buf_count(struct iris_inst *inst, enum iris_buffer_type buffer_type case BUF_INPUT: return MIN_BUFFERS; case BUF_OUTPUT: - return inst->fw_min_count; + return output_min_count(inst); case BUF_BIN: case BUF_COMV: case BUF_NON_COMV: case BUF_LINE: case BUF_PERSIST: + return internal_buffer_count(inst, buffer_type); case BUF_SCRATCH_1: return 1; /* internal buffer count needed by firmware is 1 */ case BUF_DPB: diff --git a/drivers/media/platform/qcom/iris/iris_vpu_buffer.h b/drivers/media/platform/qcom/iris/iris_vpu_buffer.h index 62af6ea6ba1fe..ee95fd20b794c 100644 --- a/drivers/media/platform/qcom/iris/iris_vpu_buffer.h +++ b/drivers/media/platform/qcom/iris/iris_vpu_buffer.h @@ -13,6 +13,10 @@ struct iris_inst; #define DMA_ALIGNMENT 256 #define NUM_HW_PIC_BUF 32 +#define LCU_MAX_SIZE_PELS 64 +#define LCU_MIN_SIZE_PELS 16 +#define HDR10_HIST_EXTRADATA_SIZE (4 * 1024) + #define SIZE_HW_PIC(size_per_buf) (NUM_HW_PIC_BUF * (size_per_buf)) #define MAX_TILE_COLUMNS 32 @@ -28,11 +32,47 @@ struct iris_inst; #define SIZE_SLIST_BUF_H264 512 #define H264_DISPLAY_BUF_SIZE 3328 #define H264_NUM_FRM_INFO 66 - -#define SIZE_SEI_USERDATA 4096 - +#define H265_NUM_TILE_COL 32 +#define H265_NUM_TILE_ROW 128 +#define H265_NUM_TILE (H265_NUM_TILE_ROW * H265_NUM_TILE_COL + 1) +#define SIZE_H265D_BSE_CMD_PER_BUF (16 * sizeof(u32)) + +#define NUM_SLIST_BUF_H265 (80 + 20) +#define SIZE_SLIST_BUF_H265 (BIT(10)) +#define H265_DISPLAY_BUF_SIZE (3072) +#define H265_NUM_FRM_INFO (48) + +#define VP9_NUM_FRAME_INFO_BUF 32 +#define VP9_NUM_PROBABILITY_TABLE_BUF (VP9_NUM_FRAME_INFO_BUF + 4) +#define VP9_PROB_TABLE_SIZE (3840) +#define VP9_FRAME_INFO_BUF_SIZE (6144) +#define BUFFER_ALIGNMENT_32_BYTES 32 +#define CCE_TILE_OFFSET_SIZE ALIGN(32 * 4 * 4, BUFFER_ALIGNMENT_32_BYTES) +#define MAX_SUPERFRAME_HEADER_LEN (34) +#define MAX_FE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE 64 +#define MAX_FE_NBR_CTRL_LCU32_LINE_BUFFER_SIZE 64 +#define MAX_FE_NBR_CTRL_LCU16_LINE_BUFFER_SIZE 64 +#define MAX_SE_NBR_CTRL_LCU16_LINE_BUFFER_SIZE (128 / 8) +#define MAX_SE_NBR_CTRL_LCU32_LINE_BUFFER_SIZE (128 / 8) +#define VP9_UDC_HEADER_BUF_SIZE (3 * 128) + +#define SIZE_SEI_USERDATA 4096 +#define SIZE_DOLBY_RPU_METADATA (41 * 1024) #define H264_CABAC_HDR_RATIO_HD_TOT 1 #define H264_CABAC_RES_RATIO_HD_TOT 3 +#define H265D_MAX_SLICE 1200 +#define SIZE_H265D_HW_PIC_T SIZE_H264D_HW_PIC_T +#define H265_CABAC_HDR_RATIO_HD_TOT 2 +#define H265_CABAC_RES_RATIO_HD_TOT 2 +#define SIZE_H265D_VPP_CMD_PER_BUF (256) + +#define VPX_DECODER_FRAME_CONCURENCY_LVL (2) +#define VPX_DECODER_FRAME_BIN_HDR_BUDGET 1 +#define VPX_DECODER_FRAME_BIN_RES_BUDGET 3 +#define VPX_DECODER_FRAME_BIN_DENOMINATOR 2 + +#define VPX_DECODER_FRAME_BIN_RES_BUDGET_RATIO (3 / 2) + #define SIZE_H264D_HW_PIC_T (BIT(11)) #define MAX_FE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE 64 diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index 378923594f024..4e4c157f29170 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -197,6 +197,8 @@ struct fastrpc_buf { struct dma_buf *dmabuf; struct device *dev; void *virt; + /* Type of buffer */ + u32 flag; u64 phys; u64 size; /* Lock for dma buf attachments */ @@ -273,10 +275,12 @@ struct fastrpc_channel_ctx { struct kref refcount; /* Flag if dsp attributes are cached */ bool valid_attributes; + /* Flag if audio PD init mem was allocated */ + bool audio_init_mem; u32 dsp_attributes[FASTRPC_MAX_DSP_ATTRIBUTES]; struct fastrpc_device *secure_fdevice; struct fastrpc_device *fdevice; - struct fastrpc_buf *remote_heap; + struct list_head rhmaps; struct list_head invoke_interrupted_mmaps; bool secure; bool unsigned_support; @@ -394,6 +398,9 @@ static int fastrpc_map_lookup(struct fastrpc_user *fl, int fd, static void fastrpc_buf_free(struct fastrpc_buf *buf) { + if (!buf) + return; + dma_free_coherent(buf->dev, buf->size, buf->virt, FASTRPC_PHYS(buf->phys)); kfree(buf); @@ -1234,12 +1241,47 @@ static bool is_session_rejected(struct fastrpc_user *fl, bool unsigned_pd_reques return false; } +static void fastrpc_cleanup_rhmaps(struct fastrpc_channel_ctx *cctx) +{ + struct fastrpc_buf *buf, *b; + struct list_head temp_list; + int err; + unsigned long flags; + + INIT_LIST_HEAD(&temp_list); + + spin_lock_irqsave(&cctx->lock, flags); + list_splice_init(&cctx->rhmaps, &temp_list); + spin_unlock_irqrestore(&cctx->lock, flags); + + list_for_each_entry_safe(buf, b, &temp_list, node) { + if (cctx->vmcount) { + u64 src_perms = 0; + struct qcom_scm_vmperm dst_perms; + u32 i; + + for (i = 0; i < cctx->vmcount; i++) + src_perms |= BIT(cctx->vmperms[i].vmid); + + dst_perms.vmid = QCOM_SCM_VMID_HLOS; + dst_perms.perm = QCOM_SCM_PERM_RWX; + err = qcom_scm_assign_mem(buf->phys, (u64)buf->size, + &src_perms, &dst_perms, 1); + if (err) + continue; + } + fastrpc_buf_free(buf); + } +} + static int fastrpc_init_create_static_process(struct fastrpc_user *fl, char __user *argp) { struct fastrpc_init_create_static init; struct fastrpc_invoke_args *args; struct fastrpc_phy_page pages[1]; + struct fastrpc_buf *buf = NULL; + u64 phys = 0, size = 0; char *name; int err; bool scm_done = false; @@ -1249,6 +1291,7 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl, u32 pageslen; } inbuf; u32 sc; + unsigned long flags; args = kcalloc(FASTRPC_CREATE_STATIC_PROCESS_NARGS, sizeof(*args), GFP_KERNEL); if (!args) @@ -1270,32 +1313,37 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl, goto err; } - if (!fl->cctx->remote_heap) { + inbuf.client_id = fl->client_id; + inbuf.namelen = init.namelen; + inbuf.pageslen = 0; + if (!fl->cctx->audio_init_mem) { err = fastrpc_remote_heap_alloc(fl, fl->sctx->dev, init.memlen, - &fl->cctx->remote_heap); + &buf); if (err) goto err_name; + phys = buf->phys; + size = buf->size; /* Map if we have any heap VMIDs associated with this ADSP Static Process. */ if (fl->cctx->vmcount) { u64 src_perms = BIT(QCOM_SCM_VMID_HLOS); - err = qcom_scm_assign_mem(fl->cctx->remote_heap->phys, - (u64)fl->cctx->remote_heap->size, - &src_perms, - fl->cctx->vmperms, fl->cctx->vmcount); + err = qcom_scm_assign_mem(phys, size, &src_perms, + fl->cctx->vmperms, fl->cctx->vmcount); if (err) { dev_err(fl->sctx->dev, "Failed to assign memory with phys 0x%llx size 0x%llx err %d\n", - fl->cctx->remote_heap->phys, fl->cctx->remote_heap->size, err); + phys, size, err); goto err_map; } scm_done = true; + spin_lock_irqsave(&fl->cctx->lock, flags); + list_add_tail(&buf->node, &fl->cctx->rhmaps); + spin_unlock_irqrestore(&fl->cctx->lock, flags); + fl->cctx->audio_init_mem = true; + inbuf.pageslen = 1; } } - inbuf.client_id = fl->client_id; - inbuf.namelen = init.namelen; - inbuf.pageslen = 0; fl->pd = USER_PD; args[0].ptr = (u64)(uintptr_t)&inbuf; @@ -1306,8 +1354,8 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl, args[1].length = inbuf.namelen; args[1].fd = -1; - pages[0].addr = fl->cctx->remote_heap->phys; - pages[0].size = fl->cctx->remote_heap->size; + pages[0].addr = phys; + pages[0].size = size; args[2].ptr = (u64)(uintptr_t) pages; args[2].length = sizeof(*pages); @@ -1325,6 +1373,11 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl, return 0; err_invoke: + if (buf) { + spin_lock_irqsave(&fl->cctx->lock, flags); + list_del(&buf->node); + spin_unlock_irqrestore(&fl->cctx->lock, flags); + } if (fl->cctx->vmcount && scm_done) { u64 src_perms = 0; struct qcom_scm_vmperm dst_perms; @@ -1335,15 +1388,15 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl, dst_perms.vmid = QCOM_SCM_VMID_HLOS; dst_perms.perm = QCOM_SCM_PERM_RWX; - err = qcom_scm_assign_mem(fl->cctx->remote_heap->phys, - (u64)fl->cctx->remote_heap->size, - &src_perms, &dst_perms, 1); + err = qcom_scm_assign_mem(phys, size, &src_perms, + &dst_perms, 1); if (err) dev_err(fl->sctx->dev, "Failed to assign memory phys 0x%llx size 0x%llx err %d\n", - fl->cctx->remote_heap->phys, fl->cctx->remote_heap->size, err); + phys, size, err); } err_map: - fastrpc_buf_free(fl->cctx->remote_heap); + fl->cctx->audio_init_mem = false; + fastrpc_buf_free(buf); err_name: kfree(name); err: @@ -1816,11 +1869,26 @@ static int fastrpc_req_munmap_impl(struct fastrpc_user *fl, struct fastrpc_buf * err = fastrpc_internal_invoke(fl, true, FASTRPC_INIT_HANDLE, sc, &args[0]); if (!err) { - dev_dbg(dev, "unmmap\tpt 0x%09lx OK\n", buf->raddr); - spin_lock(&fl->lock); - list_del(&buf->node); - spin_unlock(&fl->lock); + if (buf->flag == ADSP_MMAP_REMOTE_HEAP_ADDR && fl->cctx->vmcount) { + u64 src_perms = 0; + struct qcom_scm_vmperm dst_perms; + u32 i; + + for (i = 0; i < fl->cctx->vmcount; i++) + src_perms |= BIT(fl->cctx->vmperms[i].vmid); + + dst_perms.vmid = QCOM_SCM_VMID_HLOS; + dst_perms.perm = QCOM_SCM_PERM_RWX; + err = qcom_scm_assign_mem(buf->phys, (u64)buf->size, + &src_perms, &dst_perms, 1); + if (err) { + dev_err(fl->sctx->dev, "Failed to assign memory phys 0x%llx size 0x%llx err %d\n", + buf->phys, buf->size, err); + return err; + } + } fastrpc_buf_free(buf); + dev_dbg(dev, "unmmap\tpt 0x%09lx OK\n", buf->raddr); } else { dev_err(dev, "unmmap\tpt 0x%09lx ERROR\n", buf->raddr); } @@ -1833,26 +1901,54 @@ static int fastrpc_req_munmap(struct fastrpc_user *fl, char __user *argp) struct fastrpc_buf *buf = NULL, *iter, *b; struct fastrpc_req_munmap req; struct device *dev = fl->sctx->dev; + int err; + unsigned long flags; if (copy_from_user(&req, argp, sizeof(req))) return -EFAULT; spin_lock(&fl->lock); list_for_each_entry_safe(iter, b, &fl->mmaps, node) { - if ((iter->raddr == req.vaddrout) && (iter->size == req.size)) { + if (iter->raddr == req.vaddrout && iter->size == req.size) { + list_del(&iter->node); buf = iter; break; } } spin_unlock(&fl->lock); - if (!buf) { - dev_err(dev, "mmap\t\tpt 0x%09llx [len 0x%08llx] not in list\n", - req.vaddrout, req.size); - return -EINVAL; + if (buf) { + err = fastrpc_req_munmap_impl(fl, buf); + if (err) { + spin_lock(&fl->lock); + list_add_tail(&buf->node, &fl->mmaps); + spin_unlock(&fl->lock); + } + return err; + } + + spin_lock_irqsave(&fl->cctx->lock, flags); + list_for_each_entry_safe(iter, b, &fl->cctx->rhmaps, node) { + if (iter->raddr == req.vaddrout && iter->size == req.size) { + list_del(&iter->node); + buf = iter; + break; + } + } + spin_unlock_irqrestore(&fl->cctx->lock, flags); + if (buf) { + err = fastrpc_req_munmap_impl(fl, buf); + if (err) { + spin_lock_irqsave(&fl->cctx->lock, flags); + list_add_tail(&buf->node, &fl->cctx->rhmaps); + spin_unlock_irqrestore(&fl->cctx->lock, flags); + } + return err; } + dev_err(dev, "mmap\t\tpt 0x%09llx [len 0x%08llx] not in list\n", + req.vaddrout, req.size); - return fastrpc_req_munmap_impl(fl, buf); + return -EINVAL; } static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp) @@ -1866,6 +1962,7 @@ static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp) struct device *dev = fl->sctx->dev; int err; u32 sc; + unsigned long flags; if (copy_from_user(&req, argp, sizeof(req))) return -EFAULT; @@ -1919,6 +2016,7 @@ static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp) /* update the buffer to be able to deallocate the memory on the DSP */ buf->raddr = (uintptr_t) rsp_msg.vaddr; + buf->flag = req.flags; /* let the client know the address to use */ req.vaddrout = rsp_msg.vaddr; @@ -1934,22 +2032,34 @@ static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp) buf->phys, buf->size, err); goto err_assign; } + spin_lock_irqsave(&fl->cctx->lock, flags); + list_add_tail(&buf->node, &fl->cctx->rhmaps); + spin_unlock_irqrestore(&fl->cctx->lock, flags); + } else { + spin_lock(&fl->lock); + list_add_tail(&buf->node, &fl->mmaps); + spin_unlock(&fl->lock); } - spin_lock(&fl->lock); - list_add_tail(&buf->node, &fl->mmaps); - spin_unlock(&fl->lock); - if (copy_to_user((void __user *)argp, &req, sizeof(req))) { err = -EFAULT; - goto err_assign; + goto err_copy; } dev_dbg(dev, "mmap\t\tpt 0x%09lx OK [len 0x%08llx]\n", buf->raddr, buf->size); return 0; - +err_copy: + if (req.flags == ADSP_MMAP_REMOTE_HEAP_ADDR) { + spin_lock_irqsave(&fl->cctx->lock, flags); + list_del(&buf->node); + spin_unlock_irqrestore(&fl->cctx->lock, flags); + } else { + spin_lock(&fl->lock); + list_del(&buf->node); + spin_unlock(&fl->lock); + } err_assign: fastrpc_req_munmap_impl(fl, buf); @@ -2359,6 +2469,7 @@ static int fastrpc_rpmsg_probe(struct rpmsg_device *rpdev) rdev->dma_mask = &data->dma_mask; dma_set_mask_and_coherent(rdev, DMA_BIT_MASK(32)); INIT_LIST_HEAD(&data->users); + INIT_LIST_HEAD(&data->rhmaps); INIT_LIST_HEAD(&data->invoke_interrupted_mmaps); spin_lock_init(&data->lock); idr_init(&data->ctx_idr); @@ -2417,8 +2528,7 @@ static void fastrpc_rpmsg_remove(struct rpmsg_device *rpdev) list_for_each_entry_safe(buf, b, &cctx->invoke_interrupted_mmaps, node) list_del(&buf->node); - if (cctx->remote_heap) - fastrpc_buf_free(cctx->remote_heap); + fastrpc_cleanup_rhmaps(cctx); of_platform_depopulate(&rpdev->dev); diff --git a/drivers/pci/controller/dwc/Kconfig b/drivers/pci/controller/dwc/Kconfig index d9f0386396edf..fee00158676ca 100644 --- a/drivers/pci/controller/dwc/Kconfig +++ b/drivers/pci/controller/dwc/Kconfig @@ -292,6 +292,7 @@ config PCIE_QCOM_COMMON config PCIE_QCOM bool "Qualcomm PCIe controller (host mode)" depends on OF && (ARCH_QCOM || COMPILE_TEST) + depends on QCOM_COMMAND_DB || QCOM_COMMAND_DB=n depends on PCI_MSI select PCIE_DW_HOST select CRC8 diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c index c789e3f856550..b12da8978f8f6 100644 --- a/drivers/pci/controller/dwc/pcie-qcom.c +++ b/drivers/pci/controller/dwc/pcie-qcom.c @@ -32,14 +32,19 @@ #include #include #include +#include #include "../../pci.h" #include "pcie-designware.h" #include "pcie-qcom-common.h" +#include +#include + /* PARF registers */ #define PARF_SYS_CTRL 0x00 #define PARF_PM_CTRL 0x20 +#define PARF_PM_STTS 0x24 #define PARF_PCS_DEEMPH 0x34 #define PARF_PCS_SWING 0x38 #define PARF_PHY_CTRL 0x40 @@ -70,6 +75,7 @@ /* ELBI registers */ #define ELBI_SYS_CTRL 0x04 +#define ELBI_SYS_CTRL_PME_TURNOFF_MSG BIT(4) /* DBI registers */ #define AXI_MSTR_RESP_COMP_CTRL0 0x818 @@ -94,7 +100,10 @@ #define L1_CLK_RMV_DIS BIT(1) /* PARF_PM_CTRL register fields */ -#define REQ_NOT_ENTR_L1 BIT(5) +#define REQ_NOT_ENTR_L1 BIT(5) /* "Prevent L0->L1" */ + +/* PARF_PM_STTS register fields */ +#define PM_ENTER_L23 BIT(5) /* PARF_PCS_DEEMPH register fields */ #define PCS_DEEMPH_TX_DEEMPH_GEN1(x) FIELD_PREP(GENMASK(21, 16), x) @@ -147,6 +156,7 @@ /* ELBI_SYS_CTRL register fields */ #define ELBI_SYS_CTRL_LT_ENABLE BIT(0) +#define ELBI_SYS_CTRL_PME_TURNOFF_MSG BIT(4) /* AXI_MSTR_RESP_COMP_CTRL0 register fields */ #define CFG_REMOTE_RD_REQ_BRIDGE_SIZE_2K 0x4 @@ -276,6 +286,7 @@ struct qcom_pcie { struct dentry *debugfs; bool suspended; bool use_pm_opp; + bool soc_is_rpmh; }; #define to_qcom_pcie(x) dev_get_drvdata((x)->dev) @@ -310,6 +321,24 @@ static int qcom_pcie_start_link(struct dw_pcie *pci) return 0; } +static int qcom_pcie_stop_link(struct dw_pcie *pci) +{ + struct qcom_pcie *pcie = to_qcom_pcie(pci); + u32 ret_l23, val; + + writel(ELBI_SYS_CTRL_PME_TURNOFF_MSG, pcie->elbi + ELBI_SYS_CTRL); + readl(pcie->elbi + ELBI_SYS_CTRL); + + ret_l23 = readl_poll_timeout(pcie->parf + PARF_PM_STTS, val, + val & PM_ENTER_L23, 10000, 100000); + if (ret_l23) { + dev_err(pci->dev, "Failed to enter L2/L3\n"); + return -ETIMEDOUT; + } + + return 0; +} + static void qcom_pcie_clear_aspm_l0s(struct dw_pcie *pci) { struct qcom_pcie *pcie = to_qcom_pcie(pci); @@ -944,27 +973,27 @@ static int qcom_pcie_init_2_7_0(struct qcom_pcie *pcie) return ret; } - ret = clk_bulk_prepare_enable(res->num_clks, res->clks); - if (ret < 0) - goto err_disable_regulators; - + /* Assert the reset to hold the RC in a known state */ ret = reset_control_assert(res->rst); if (ret) { dev_err(dev, "reset assert failed (%d)\n", ret); - goto err_disable_clocks; + goto err_disable_regulators; } - usleep_range(1000, 1500); + /* GCC_PCIE_n_AUX_CLK won't come up if the reset is asserted */ ret = reset_control_deassert(res->rst); if (ret) { dev_err(dev, "reset deassert failed (%d)\n", ret); - goto err_disable_clocks; + goto err_disable_regulators; } - /* Wait for reset to complete, required on SM8450 */ usleep_range(1000, 1500); + ret = clk_bulk_prepare_enable(res->num_clks, res->clks); + if (ret < 0) + goto err_disable_regulators; + /* configure PCIe to RC mode */ writel(DEVICE_TYPE_RC, pcie->parf + PARF_DEVICE_TYPE); @@ -994,8 +1023,6 @@ static int qcom_pcie_init_2_7_0(struct qcom_pcie *pcie) writel(val, pcie->parf + PARF_AXI_MSTR_WR_ADDR_HALT_V2); return 0; -err_disable_clocks: - clk_bulk_disable_unprepare(res->num_clks, res->clks); err_disable_regulators: regulator_bulk_disable(ARRAY_SIZE(res->supplies), res->supplies); @@ -1038,9 +1065,19 @@ static void qcom_pcie_host_post_init_2_7_0(struct qcom_pcie *pcie) static void qcom_pcie_deinit_2_7_0(struct qcom_pcie *pcie) { struct qcom_pcie_resources_2_7_0 *res = &pcie->res.v2_7_0; + u32 val; + + /* Disable PCIe clocks and resets */ + val = readl(pcie->parf + PARF_PHY_CTRL); + val |= PHY_TEST_PWR_DOWN; + writel(val, pcie->parf + PARF_PHY_CTRL); + readl(pcie->parf + PARF_PHY_CTRL); clk_bulk_disable_unprepare(res->num_clks, res->clks); + reset_control_assert(res->rst); + usleep_range(2000, 2500); + regulator_bulk_disable(ARRAY_SIZE(res->supplies), res->supplies); } @@ -1736,6 +1773,9 @@ static int qcom_pcie_probe(struct platform_device *pdev) pcie->parf + PARF_INT_ALL_MASK); } + /* If the soc features RPMh, cmd_db must have been prepared by now */ + pcie->soc_is_rpmh = !cmd_db_ready(); + qcom_pcie_icc_opp_update(pcie); if (pcie->mhi) @@ -1754,86 +1794,123 @@ static int qcom_pcie_probe(struct platform_device *pdev) return ret; } -static int qcom_pcie_suspend_noirq(struct device *dev) +static int qcom_pcie_resume_noirq(struct device *dev) { struct qcom_pcie *pcie = dev_get_drvdata(dev); - int ret = 0; + int ret; - /* - * Set minimum bandwidth required to keep data path functional during - * suspend. - */ - if (pcie->icc_mem) { - ret = icc_set_bw(pcie->icc_mem, 0, kBps_to_icc(1)); + if (pcie->soc_is_rpmh) { + /* + * Undo the tag change from qcom_pcie_suspend_noirq first in + * case RPMh spontaneously decides to power collapse the + * platform based on other inputs. + */ + icc_set_tag(pcie->icc_mem, QCOM_ICC_TAG_ALWAYS); + + /* Flush the tag change */ + ret = icc_enable(pcie->icc_mem); if (ret) { - dev_err(dev, - "Failed to set bandwidth for PCIe-MEM interconnect path: %d\n", - ret); + dev_err(pcie->pci->dev, "failed to icc_enable: %d", ret); return ret; } } - /* - * Turn OFF the resources only for controllers without active PCIe - * devices. For controllers with active devices, the resources are kept - * ON and the link is expected to be in L0/L1 (sub)states. - * - * Turning OFF the resources for controllers with active PCIe devices - * will trigger access violation during the end of the suspend cycle, - * as kernel tries to access the PCIe devices config space for masking - * MSIs. - * - * Also, it is not desirable to put the link into L2/L3 state as that - * implies VDD supply will be removed and the devices may go into - * powerdown state. This will affect the lifetime of the storage devices - * like NVMe. - */ - if (!dw_pcie_link_up(pcie->pci)) { - qcom_pcie_host_deinit(&pcie->pci->pp); - pcie->suspended = true; + /* Only check this now to make sure the icc tag has been set. */ + if (!pcie->suspended) + return 0; + + ret = icc_enable(pcie->icc_cpu); + if (ret) { + dev_err(dev, "Failed to enable CPU-PCIe interconnect path: %d\n", ret); + goto revert_icc_tag; } - /* - * Only disable CPU-PCIe interconnect path if the suspend is non-S2RAM. - * Because on some platforms, DBI access can happen very late during the - * S2RAM and a non-active CPU-PCIe interconnect path may lead to NoC - * error. - */ - if (pm_suspend_target_state != PM_SUSPEND_MEM) { - ret = icc_disable(pcie->icc_cpu); - if (ret) - dev_err(dev, "Failed to disable CPU-PCIe interconnect path: %d\n", ret); + ret = qcom_pcie_host_init(&pcie->pci->pp); + if (ret) + goto revert_icc_tag; + + dw_pcie_setup_rc(&pcie->pci->pp); + + ret = qcom_pcie_start_link(pcie->pci); + if (ret) + goto deinit_host; + + /* Ignore the retval, the devices may come up later. */ + dw_pcie_wait_for_link(pcie->pci); - if (pcie->use_pm_opp) - dev_pm_opp_set_opp(pcie->pci->dev, NULL); + qcom_pcie_icc_opp_update(pcie); + + pcie->suspended = false; + + return 0; + +deinit_host: + qcom_pcie_host_deinit(&pcie->pci->pp); +revert_icc_tag: + if (pcie->soc_is_rpmh) { + icc_set_tag(pcie->icc_mem, QCOM_ICC_TAG_WAKE); + + /* Ignore the retval, failing here would be tragic anyway.. */ + icc_enable(pcie->icc_mem); } + return ret; } -static int qcom_pcie_resume_noirq(struct device *dev) +static int qcom_pcie_suspend_noirq(struct device *dev) { struct qcom_pcie *pcie = dev_get_drvdata(dev); - int ret; + int ret = 0; + + if (pcie->suspended) + return 0; + + if (dw_pcie_link_up(pcie->pci)) { + ret = qcom_pcie_stop_link(pcie->pci); + if (ret) + return ret; + } + + qcom_pcie_host_deinit(&pcie->pci->pp); - if (pm_suspend_target_state != PM_SUSPEND_MEM) { - ret = icc_enable(pcie->icc_cpu); + if (pcie->soc_is_rpmh) { + /* + * The PCIe RC may be covertly accessed by the secure firmware + * on sleep exit. Use the WAKE bucket to let RPMh pull the plug + * on PCIe in sleep, but guarantee it comes back up for resume. + */ + icc_set_tag(pcie->icc_mem, QCOM_ICC_TAG_WAKE); + + /* Flush the tag change */ + ret = icc_enable(pcie->icc_mem); if (ret) { - dev_err(dev, "Failed to enable CPU-PCIe interconnect path: %d\n", ret); + dev_err(pcie->pci->dev, "failed to icc_enable %d\n", ret); + + /* Revert everything and pray icc calls succeed */ + return qcom_pcie_resume_noirq(dev); + } + } else { + /* + * Set minimum bandwidth required to keep data path functional + * during suspend. + */ + ret = icc_set_bw(pcie->icc_mem, 0, kBps_to_icc(1)); + if (ret) { + dev_err(dev, "Failed to set interconnect bandwidth: %d\n", ret); return ret; } } - if (pcie->suspended) { - ret = qcom_pcie_host_init(&pcie->pci->pp); - if (ret) - return ret; + pcie->suspended = true; - pcie->suspended = false; - } + ret = icc_disable(pcie->icc_cpu); + if (ret) + dev_err(dev, "Failed to disable CPU-PCIe interconnect path: %d\n", ret); - qcom_pcie_icc_opp_update(pcie); + if (pcie->use_pm_opp) + dev_pm_opp_set_opp(pcie->pci->dev, NULL); - return 0; + return ret; } static const struct of_device_id qcom_pcie_match[] = { @@ -1863,6 +1940,7 @@ static const struct of_device_id qcom_pcie_match[] = { { .compatible = "qcom,pcie-sm8450-pcie1", .data = &cfg_1_9_0 }, { .compatible = "qcom,pcie-sm8550", .data = &cfg_1_9_0 }, { .compatible = "qcom,pcie-x1e80100", .data = &cfg_sc8280xp }, + { .compatible = "qcom,qcs615-pcie", .data = &cfg_1_9_0 }, { } }; diff --git a/drivers/rpmsg/qcom_glink_smem.c b/drivers/rpmsg/qcom_glink_smem.c index 7a982c60a8ddc..9eba0aaae916a 100644 --- a/drivers/rpmsg/qcom_glink_smem.c +++ b/drivers/rpmsg/qcom_glink_smem.c @@ -86,9 +86,14 @@ static size_t glink_smem_rx_avail(struct qcom_glink_pipe *np) tail = le32_to_cpu(*pipe->tail); if (head < tail) - return pipe->native.length - tail + head; + len = pipe->native.length - tail + head; else - return head - tail; + len = head - tail; + + if (WARN_ON_ONCE(len > pipe->native.length)) + len = 0; + + return len; } static void glink_smem_rx_peek(struct qcom_glink_pipe *np, @@ -99,6 +104,10 @@ static void glink_smem_rx_peek(struct qcom_glink_pipe *np, u32 tail; tail = le32_to_cpu(*pipe->tail); + + if (WARN_ON_ONCE(tail > pipe->native.length)) + return; + tail += offset; if (tail >= pipe->native.length) tail -= pipe->native.length; @@ -121,7 +130,7 @@ static void glink_smem_rx_advance(struct qcom_glink_pipe *np, tail += count; if (tail >= pipe->native.length) - tail -= pipe->native.length; + tail %= pipe->native.length; *pipe->tail = cpu_to_le32(tail); } @@ -146,6 +155,9 @@ static size_t glink_smem_tx_avail(struct qcom_glink_pipe *np) else avail -= FIFO_FULL_RESERVE + TX_BLOCKED_CMD_RESERVE; + if (WARN_ON_ONCE(avail > pipe->native.length)) + avail = 0; + return avail; } @@ -155,6 +167,9 @@ static unsigned int glink_smem_tx_write_one(struct glink_smem_pipe *pipe, { size_t len; + if (WARN_ON_ONCE(head > pipe->native.length)) + return head; + len = min_t(size_t, count, pipe->native.length - head); if (len) memcpy(pipe->fifo + head, data, len); diff --git a/drivers/soc/qcom/qcom-geni-se.c b/drivers/soc/qcom/qcom-geni-se.c index 4cb959106efa9..ad9595275a9ec 100644 --- a/drivers/soc/qcom/qcom-geni-se.c +++ b/drivers/soc/qcom/qcom-geni-se.c @@ -1,11 +1,15 @@ // SPDX-License-Identifier: GPL-2.0 -// Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* + * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved. + */ /* Disable MMIO tracing to prevent excessive logging of unwanted MMIO traces */ #define __DISABLE_TRACE_MMIO__ #include #include +#include #include #include #include @@ -15,6 +19,7 @@ #include #include #include +#include /** * DOC: Overview @@ -80,9 +85,9 @@ * common to all the serial engines and are independent of serial interfaces. */ -#define MAX_CLK_PERF_LEVEL 32 -#define MAX_CLKS 2 - +#define MAX_CLK_PERF_LEVEL 32 +#define MAX_CLKS 2 +#define MAX_PROTOCOL 6 /** * struct geni_wrapper - Data structure to represent the QUP Wrapper Core * @dev: Device pointer of the QUP wrapper core @@ -110,28 +115,23 @@ struct geni_se_desc { static const char * const icc_path_names[] = {"qup-core", "qup-config", "qup-memory"}; +static const char * const protocol_name[MAX_PROTOCOL] = { "None", "SPI", "UART", + "I2C", "I3C", "SPI SLAVE"}; + #define QUP_HW_VER_REG 0x4 /* Common SE registers */ -#define GENI_INIT_CFG_REVISION 0x0 -#define GENI_S_INIT_CFG_REVISION 0x4 -#define GENI_OUTPUT_CTRL 0x24 -#define GENI_CGC_CTRL 0x28 #define GENI_CLK_CTRL_RO 0x60 -#define GENI_FW_S_REVISION_RO 0x6c #define SE_GENI_BYTE_GRAN 0x254 #define SE_GENI_TX_PACKING_CFG0 0x260 #define SE_GENI_TX_PACKING_CFG1 0x264 #define SE_GENI_RX_PACKING_CFG0 0x284 #define SE_GENI_RX_PACKING_CFG1 0x288 -#define SE_GENI_M_GP_LENGTH 0x910 -#define SE_GENI_S_GP_LENGTH 0x914 #define SE_DMA_TX_PTR_L 0xc30 #define SE_DMA_TX_PTR_H 0xc34 #define SE_DMA_TX_ATTR 0xc38 #define SE_DMA_TX_LEN 0xc3c #define SE_DMA_TX_IRQ_EN 0xc48 -#define SE_DMA_TX_IRQ_EN_SET 0xc4c #define SE_DMA_TX_IRQ_EN_CLR 0xc50 #define SE_DMA_TX_LEN_IN 0xc54 #define SE_DMA_TX_MAX_BURST 0xc5c @@ -140,9 +140,7 @@ static const char * const icc_path_names[] = {"qup-core", "qup-config", #define SE_DMA_RX_ATTR 0xd38 #define SE_DMA_RX_LEN 0xd3c #define SE_DMA_RX_IRQ_EN 0xd48 -#define SE_DMA_RX_IRQ_EN_SET 0xd4c #define SE_DMA_RX_IRQ_EN_CLR 0xd50 -#define SE_DMA_RX_LEN_IN 0xd54 #define SE_DMA_RX_MAX_BURST 0xd5c #define SE_DMA_RX_FLUSH 0xd60 #define SE_GSI_EVENT_EN 0xe18 @@ -179,7 +177,7 @@ static const char * const icc_path_names[] = {"qup-core", "qup-config", /* SE_DMA_GENERAL_CFG */ #define DMA_RX_CLK_CGC_ON BIT(0) #define DMA_TX_CLK_CGC_ON BIT(1) -#define DMA_AHB_SLV_CFG_ON BIT(2) +#define DMA_AHB_SLV_CLK_CGC_ON BIT(2) #define AHB_SEC_SLV_CLK_CGC_ON BIT(3) #define DUMMY_RX_NON_BUFFERABLE BIT(4) #define RX_DMA_ZERO_PADDING_EN BIT(5) @@ -220,12 +218,12 @@ static void geni_se_io_init(void __iomem *base) { u32 val; - val = readl_relaxed(base + GENI_CGC_CTRL); + val = readl_relaxed(base + SE_GENI_CGC_CTRL); val |= DEFAULT_CGC_EN; - writel_relaxed(val, base + GENI_CGC_CTRL); + writel_relaxed(val, base + SE_GENI_CGC_CTRL); val = readl_relaxed(base + SE_DMA_GENERAL_CFG); - val |= AHB_SEC_SLV_CLK_CGC_ON | DMA_AHB_SLV_CFG_ON; + val |= AHB_SEC_SLV_CLK_CGC_ON | DMA_AHB_SLV_CLK_CGC_ON; val |= DMA_TX_CLK_CGC_ON | DMA_RX_CLK_CGC_ON; writel_relaxed(val, base + SE_DMA_GENERAL_CFG); @@ -891,6 +889,376 @@ int geni_icc_disable(struct geni_se *se) } EXPORT_SYMBOL_GPL(geni_icc_disable); +/** + * geni_read_elf() - Read an ELF file. + * @se: Pointer to the SE resources structure. + * @fw: Pointer to the firmware buffer. + * @pelfseg: Pointer to the SE-specific ELF header. + * + * Read the ELF file and output a pointer to the header data, which + * contains the firmware data and any other details. + * + * Return: 0 if successful, otherwise return an error value. + */ +static int geni_read_elf(struct geni_se *se, const struct firmware *fw, struct elf_se_hdr **pelfseg) +{ + const struct elf32_hdr *ehdr; + struct elf32_phdr *phdrs, *phdr; + const struct elf_se_hdr *elfseg; + const u8 *addr; + int i; + + if (!fw || fw->size < sizeof(struct elf32_hdr)) + return -EINVAL; + + ehdr = (struct elf32_hdr *)fw->data; + phdrs = (struct elf32_phdr *)(ehdr + 1); + + if (ehdr->e_phnum < 2) + return -EINVAL; + + for (i = 0; i < ehdr->e_phnum; i++) { + phdr = &phdrs[i]; + + if (fw->size < phdr->p_offset + phdr->p_filesz) + return -EINVAL; + + if (phdr->p_type != PT_LOAD || !phdr->p_memsz) + continue; + + if (MI_PBT_PAGE_MODE_VALUE(phdr->p_flags) != MI_PBT_NON_PAGED_SEGMENT || + MI_PBT_SEGMENT_TYPE_VALUE(phdr->p_flags) == MI_PBT_HASH_SEGMENT || + MI_PBT_ACCESS_TYPE_VALUE(phdr->p_flags) == MI_PBT_NOTUSED_SEGMENT || + MI_PBT_ACCESS_TYPE_VALUE(phdr->p_flags) == MI_PBT_SHARED_SEGMENT) + continue; + + if (phdr->p_filesz < sizeof(struct elf_se_hdr)) + continue; + + addr = fw->data + phdr->p_offset; + elfseg = (const struct elf_se_hdr *)addr; + + if (elfseg->magic != MAGIC_NUM_SE || elfseg->version != 1) + continue; + + if (phdr->p_filesz < elfseg->fw_offset + elfseg->fw_size_in_items * sizeof(u32) || + phdr->p_filesz < elfseg->cfg_idx_offset + elfseg->cfg_items_size * sizeof(u8) || + phdr->p_filesz < elfseg->cfg_val_offset + elfseg->cfg_items_size * sizeof(u32)) + continue; + + if (elfseg->serial_protocol != se->protocol) + continue; + + *pelfseg = (struct elf_se_hdr *)addr; + return 0; + } + return -EINVAL; +} + +/** + * geni_configure_xfer_mode() - Set the transfer mode. + * @se: Pointer to a structure representing SE-related resources. + * + * Set the transfer mode to either FIFO or DMA according to the mode specified by the protocol + * driver. + * + * Return: 0 if successful, otherwise return an error value. + */ +static int geni_configure_xfer_mode(struct geni_se *se) +{ + /* Configure SE FIFO, DMA or GSI mode. */ + switch (se->mode) { + case GENI_GPI_DMA: + geni_setbits32(se->base + SE_GENI_DMA_MODE_EN, GENI_DMA_MODE_EN); + writel_relaxed(0x0, se->base + SE_IRQ_EN); + writel_relaxed(DMA_RX_EVENT_EN | DMA_TX_EVENT_EN | + GENI_M_EVENT_EN | GENI_S_EVENT_EN, + se->base + SE_GSI_EVENT_EN); + break; + + case GENI_SE_FIFO: + geni_clrbits32(se->base + SE_GENI_DMA_MODE_EN, GENI_DMA_MODE_EN); + writel_relaxed(DMA_RX_IRQ_EN | DMA_TX_IRQ_EN | GENI_M_IRQ_EN | GENI_S_IRQ_EN, + se->base + SE_IRQ_EN); + writel_relaxed(0x0, se->base + SE_GSI_EVENT_EN); + break; + + case GENI_SE_DMA: + geni_setbits32(se->base + SE_GENI_DMA_MODE_EN, GENI_DMA_MODE_EN); + writel_relaxed(DMA_RX_IRQ_EN | DMA_TX_IRQ_EN | GENI_M_IRQ_EN | GENI_S_IRQ_EN, + se->base + SE_IRQ_EN); + writel_relaxed(0x0, se->base + SE_GSI_EVENT_EN); + break; + + default: + dev_err(se->dev, "Invalid geni-se transfer mode: %d\n", se->mode); + return -EINVAL; + } + return 0; +} + +/** + * geni_enable_interrupts() - Enable interrupts. + * @se: Pointer to a structure representing SE-related resources. + * + * Enable the required interrupts during the firmware load process. + * + */ +static void geni_enable_interrupts(struct geni_se *se) +{ + u32 reg_value; + + /* Enable required interrupts. */ + writel_relaxed(M_COMMON_GENI_M_IRQ_EN, se->base + SE_GENI_M_IRQ_EN); + + reg_value = S_CMD_OVERRUN_EN | S_ILLEGAL_CMD_EN | + S_CMD_CANCEL_EN | S_CMD_ABORT_EN | + S_GP_IRQ_0_EN | S_GP_IRQ_1_EN | + S_GP_IRQ_2_EN | S_GP_IRQ_3_EN | + S_RX_FIFO_WR_ERR_EN | S_RX_FIFO_RD_ERR_EN; + writel_relaxed(reg_value, se->base + SE_GENI_S_IRQ_ENABLE); + + /* DMA mode configuration. */ + reg_value = RESET_DONE_EN | SBE_EN | DMA_DONE_EN; + writel_relaxed(reg_value, se->base + SE_DMA_TX_IRQ_EN_SET); + reg_value = FLUSH_DONE_EN | RESET_DONE_EN | SBE_EN | DMA_DONE_EN; + writel_relaxed(reg_value, se->base + SE_DMA_RX_IRQ_EN_SET); +} + +/** + * geni_write_fw_revision() - Write the firmware revision. + * @se: Pointer to a structure representing SE-related resources. + * @serial_protocol: serial protocol type. + * @fw_version: QUP firmware version. + * + * Write the firmware revision and protocol into the respective register. + * + * Return: None. + */ +static void geni_write_fw_revision(struct geni_se *se, u16 serial_protocol, u16 fw_version) +{ + u32 reg_value; + + reg_value = FIELD_PREP(FW_REV_PROTOCOL_MSK, serial_protocol); + reg_value |= FIELD_PREP(FW_REV_VERSION_MSK, fw_version); + + writel_relaxed(reg_value, se->base + SE_GENI_FW_REVISION); + writel_relaxed(reg_value, se->base + SE_S_FW_REVISION); +} + +/** + * geni_load_se_fw() - Load Serial Engine specific firmware. + * @se: Pointer to a structure representing SE-related resources. + * @fw: Pointer to the firmware structure. + * + * Load the protocol firmware into the IRAM of the Serial Engine. + * + * Return: 0 if successful, otherwise return an error value. + */ +static int geni_load_se_fw(struct geni_se *se, const struct firmware *fw) +{ + const u32 *fw_data, *cfg_val_arr; + const u8 *cfg_idx_arr; + u32 i, reg_value, ramn_cnt; + int ret; + struct elf_se_hdr *hdr; + + ret = geni_read_elf(se, fw, &hdr); + if (ret) { + dev_err(se->dev, "ELF parsing failed ret: %d\n", ret); + return ret; + } + + ramn_cnt = hdr->fw_size_in_items; + if (hdr->fw_size_in_items % 2 != 0) + ramn_cnt++; + + if (ramn_cnt >= MAX_GENI_CFG_RAMn_CNT) + return -EINVAL; + + ret = geni_icc_set_bw(se); + if (ret) + return ret; + + ret = geni_icc_enable(se); + if (ret) + return ret; + + ret = geni_se_resources_on(se); + if (ret) + goto err; + + ramn_cnt = hdr->fw_size_in_items; + if (hdr->fw_size_in_items % 2 != 0) + ramn_cnt++; + + if (ramn_cnt >= MAX_GENI_CFG_RAMn_CNT) + goto err_resource; + + fw_data = (const u32 *)((u8 *)hdr + hdr->fw_offset); + cfg_idx_arr = (const u8 *)hdr + hdr->cfg_idx_offset; + cfg_val_arr = (const u32 *)((u8 *)hdr + hdr->cfg_val_offset); + + /* Disable high priority interrupt until current low priority interrupts are handled. */ + geni_setbits32(se->wrapper->base + QUPV3_COMMON_CFG, FAST_SWITCH_TO_HIGH_DISABLE); + + /* Set AHB_M_CLK_CGC_ON to indicate hardware controls se-wrapper cgc clock. */ + geni_setbits32(se->wrapper->base + QUPV3_SE_AHB_M_CFG, AHB_M_CLK_CGC_ON); + + /* Let hardware to control common cgc. */ + geni_setbits32(se->wrapper->base + QUPV3_COMMON_CGC_CTRL, COMMON_CSR_SLV_CLK_CGC_ON); + + /* Allows to drive corresponding data according to hardware value. */ + writel_relaxed(0x0, se->base + GENI_OUTPUT_CTRL); + + /* Set SCLK and HCLK to program RAM */ + geni_setbits32(se->base + SE_GENI_CGC_CTRL, PROG_RAM_SCLK_OFF | PROG_RAM_HCLK_OFF); + writel_relaxed(0x0, se->base + SE_GENI_CLK_CTRL); + geni_clrbits32(se->base + SE_GENI_CGC_CTRL, PROG_RAM_SCLK_OFF | PROG_RAM_HCLK_OFF); + + /* Enable required clocks for DMA CSR, TX and RX. */ + reg_value = AHB_SEC_SLV_CLK_CGC_ON | DMA_AHB_SLV_CLK_CGC_ON | + DMA_TX_CLK_CGC_ON | DMA_RX_CLK_CGC_ON; + geni_setbits32(se->base + SE_DMA_GENERAL_CFG, reg_value); + + /* Let hardware control CGC by default. */ + writel_relaxed(DEFAULT_CGC_EN, se->base + SE_GENI_CGC_CTRL); + + /* Set version of the configuration register part of firmware. */ + writel_relaxed(hdr->cfg_version, se->base + SE_GENI_INIT_CFG_REVISION); + writel_relaxed(hdr->cfg_version, se->base + SE_GENI_S_INIT_CFG_REVISION); + + /* Configure GENI primitive table. */ + for (i = 0; i < hdr->cfg_items_size; i++) + writel_relaxed(cfg_val_arr[i], + se->base + SE_GENI_CFG_REG0 + (cfg_idx_arr[i] * sizeof(u32))); + + /* Configure condition for assertion of RX_RFR_WATERMARK condition. */ + reg_value = geni_se_get_rx_fifo_depth(se); + writel_relaxed(reg_value - 2, se->base + SE_GENI_RX_RFR_WATERMARK_REG); + + /* Let hardware control CGC */ + geni_setbits32(se->base + GENI_OUTPUT_CTRL, DEFAULT_IO_OUTPUT_CTRL_MSK); + + ret = geni_configure_xfer_mode(se); + if (ret) + goto err_resource; + + geni_enable_interrupts(se); + + geni_write_fw_revision(se, hdr->serial_protocol, hdr->fw_version); + + ramn_cnt = hdr->fw_size_in_items; + if (hdr->fw_size_in_items % 2 != 0) + ramn_cnt++; + + if (ramn_cnt >= MAX_GENI_CFG_RAMn_CNT) + goto err_resource; + + /* Program RAM address space. */ + memcpy_toio(se->base + SE_GENI_CFG_RAMN, fw_data, ramn_cnt * sizeof(u32)); + + /* Put default values on GENI's output pads. */ + writel_relaxed(0x1, se->base + GENI_FORCE_DEFAULT_REG); + + /* High to low SCLK and HCLK to finish RAM. */ + geni_setbits32(se->base + SE_GENI_CGC_CTRL, PROG_RAM_SCLK_OFF | PROG_RAM_HCLK_OFF); + geni_setbits32(se->base + SE_GENI_CLK_CTRL, SER_CLK_SEL); + geni_clrbits32(se->base + SE_GENI_CGC_CTRL, PROG_RAM_SCLK_OFF | PROG_RAM_HCLK_OFF); + + /* Serial engine DMA interface is enabled. */ + geni_setbits32(se->base + SE_DMA_IF_EN, DMA_IF_EN); + + /* Enable or disable FIFO interface of the serial engine. */ + if (se->mode == GENI_SE_FIFO) + geni_clrbits32(se->base + SE_FIFO_IF_DISABLE, FIFO_IF_DISABLE); + else + geni_setbits32(se->base + SE_FIFO_IF_DISABLE, FIFO_IF_DISABLE); + +err_resource: + geni_se_resources_off(se); +err: + geni_icc_disable(se); + return ret; +} + +/** + * qup_fw_load() - Initiate firmware load. + * @se: Pointer to a structure representing SE-related resources. + * @fw_name: Name of the firmware. + * + * Load the firmware into a specific SE. Read the associated ELF file, + * copy the data into a buffer in kernel space using the request_firmware API, write the + * data into the SE's IRAM register, and then free the buffers. Handle firmware loading + * and parsing for a specific protocol. + * + * Return: 0 if successful, otherwise return an error value. + */ +static int qup_fw_load(struct geni_se *se, const char *fw_name) +{ + int ret; + const struct firmware *fw; + struct device *dev = se->dev; + + ret = request_firmware(&fw, fw_name, dev); + if (ret) { + dev_err(dev, "request_firmware failed for %d: %d\n", se->protocol, ret); + return ret; + } + + ret = geni_load_se_fw(se, fw); + + release_firmware(fw); + + return ret; +} + +/** + * geni_load_se_firmware() - Initiate firmware loading. + * @se: Serial engine details. + * @protocol: Protocol (SPI, I2C, or UART) for which the firmware is to be loaded. + * + * If the device tree properties are configured to load QUP firmware and the firmware + * is not already loaded, start the firmware loading process. If the device tree properties + * are not defined, skip loading the firmware, assuming it is already loaded by TZ. + * + * Return: 0 if successful, otherwise return an error value. + */ +int geni_load_se_firmware(struct geni_se *se, enum geni_se_protocol_type protocol) +{ + const char *fw_name; + int ret; + + if (protocol >= MAX_PROTOCOL) { + dev_err(se->dev, "Invalid geni-se protocol: %d", protocol); + return -EINVAL; + } + + ret = device_property_read_string(se->wrapper->dev, "firmware-name", &fw_name); + if (ret) + return -EINVAL; + + se->protocol = protocol; + + if (of_property_read_bool(se->dev->of_node, "qcom,enable-gsi-dma")) + se->mode = GENI_GPI_DMA; + else + se->mode = GENI_SE_FIFO; + + /* GSI mode is not supported by the UART driver; therefore, setting FIFO mode */ + if (protocol == GENI_SE_UART) + se->mode = GENI_SE_FIFO; + + ret = qup_fw_load(se, fw_name); + if (ret) + return ret; + + dev_dbg(se->dev, "Firmware load for %s protocol is successful for xfer mode %d\n", + protocol_name[se->protocol], se->mode); + return 0; +} +EXPORT_SYMBOL_GPL(geni_load_se_firmware); + static int geni_se_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; diff --git a/drivers/spi/spi-geni-qcom.c b/drivers/spi/spi-geni-qcom.c index 768d7482102ad..a0d8d3425c6c6 100644 --- a/drivers/spi/spi-geni-qcom.c +++ b/drivers/spi/spi-geni-qcom.c @@ -671,6 +671,12 @@ static int spi_geni_init(struct spi_geni_master *mas) goto out_pm; } spi_slv_setup(mas); + } else if (proto == GENI_SE_INVALID_PROTO) { + ret = geni_load_se_firmware(se, GENI_SE_SPI); + if (ret) { + dev_err(mas->dev, "spi master firmware load failed ret: %d\n", ret); + goto out_pm; + } } else if (proto != GENI_SE_SPI) { dev_err(mas->dev, "Invalid proto %d\n", proto); goto out_pm; diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c index 0293b6210aa67..9f905ae3c1276 100644 --- a/drivers/tty/serial/qcom_geni_serial.c +++ b/drivers/tty/serial/qcom_geni_serial.c @@ -1161,7 +1161,13 @@ static int qcom_geni_serial_port_setup(struct uart_port *uport) int ret; proto = geni_se_read_proto(&port->se); - if (proto != GENI_SE_UART) { + if (proto == GENI_SE_INVALID_PROTO) { + ret = geni_load_se_firmware(&port->se, GENI_SE_UART); + if (ret) { + dev_err(uport->dev, "UART firmware load failed ret: %d\n", ret); + return ret; + } + } else if (proto != GENI_SE_UART) { dev_err(uport->dev, "Invalid FW loaded, proto: %d\n", proto); return -ENXIO; } diff --git a/include/linux/soc/qcom/geni-se.h b/include/linux/soc/qcom/geni-se.h index 2996a3c28ef3e..c6c01c3cf8193 100644 --- a/include/linux/soc/qcom/geni-se.h +++ b/include/linux/soc/qcom/geni-se.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2023-2025 Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef _LINUX_QCOM_GENI_SE @@ -36,6 +37,7 @@ enum geni_se_protocol_type { GENI_SE_I2C, GENI_SE_I3C, GENI_SE_SPI_SLAVE, + GENI_SE_INVALID_PROTO = 255, }; struct geni_wrapper; @@ -61,6 +63,8 @@ struct geni_icc_path { * @num_clk_levels: Number of valid clock levels in clk_perf_tbl * @clk_perf_tbl: Table of clock frequency input to serial engine clock * @icc_paths: Array of ICC paths for SE + * @mode: Transfer mode se fifo, dma or gsi. + * @protocol: Protocol spi or i2c or serial. */ struct geni_se { void __iomem *base; @@ -70,24 +74,32 @@ struct geni_se { unsigned int num_clk_levels; unsigned long *clk_perf_tbl; struct geni_icc_path icc_paths[3]; + enum geni_se_xfer_mode mode; + enum geni_se_protocol_type protocol; }; /* Common SE registers */ +#define SE_GENI_INIT_CFG_REVISION 0x0 +#define SE_GENI_S_INIT_CFG_REVISION 0x4 #define GENI_FORCE_DEFAULT_REG 0x20 #define GENI_OUTPUT_CTRL 0x24 +#define SE_GENI_CGC_CTRL 0x28 #define SE_GENI_STATUS 0x40 #define GENI_SER_M_CLK_CFG 0x48 #define GENI_SER_S_CLK_CFG 0x4c #define GENI_IF_DISABLE_RO 0x64 -#define GENI_FW_REVISION_RO 0x68 +#define SE_GENI_FW_REVISION_RO 0x68 +#define SE_GENI_S_FW_REVISION_RO 0x6c #define SE_GENI_CLK_SEL 0x7c #define SE_GENI_CFG_SEQ_START 0x84 +#define SE_GENI_CFG_REG0 0x100 #define SE_GENI_DMA_MODE_EN 0x258 #define SE_GENI_M_CMD0 0x600 #define SE_GENI_M_CMD_CTRL_REG 0x604 #define SE_GENI_M_IRQ_STATUS 0x610 #define SE_GENI_M_IRQ_EN 0x614 #define SE_GENI_M_IRQ_CLEAR 0x618 +#define SE_GENI_S_IRQ_ENABLE 0x644 #define SE_GENI_M_IRQ_EN_SET 0x61c #define SE_GENI_M_IRQ_EN_CLEAR 0x620 #define SE_GENI_S_CMD0 0x630 @@ -109,13 +121,22 @@ struct geni_se { #define SE_GENI_S_GP_LENGTH 0x914 #define SE_DMA_TX_IRQ_STAT 0xc40 #define SE_DMA_TX_IRQ_CLR 0xc44 +#define SE_DMA_TX_IRQ_EN_SET 0xc4c #define SE_DMA_TX_FSM_RST 0xc58 #define SE_DMA_RX_IRQ_STAT 0xd40 #define SE_DMA_RX_IRQ_CLR 0xd44 +#define SE_DMA_RX_IRQ_EN_SET 0xd4c #define SE_DMA_RX_LEN_IN 0xd54 #define SE_DMA_RX_FSM_RST 0xd58 #define SE_HW_PARAM_0 0xe24 #define SE_HW_PARAM_1 0xe28 +#define SE_DMA_GENERAL_CFG 0xe30 +#define SE_GENI_FW_REVISION 0x1000 +#define SE_S_FW_REVISION 0x1004 +#define SE_GENI_CFG_RAMN 0x1010 +#define SE_GENI_CLK_CTRL 0x2000 +#define SE_DMA_IF_EN 0x2004 +#define SE_FIFO_IF_DISABLE 0x2008 /* GENI_FORCE_DEFAULT_REG fields */ #define FORCE_DEFAULT BIT(0) @@ -137,7 +158,7 @@ struct geni_se { /* GENI_FW_REVISION_RO fields */ #define FW_REV_PROTOCOL_MSK GENMASK(15, 8) -#define FW_REV_PROTOCOL_SHFT 8 +#define FW_REV_VERSION_MSK GENMASK(7, 0) /* GENI_CLK_SEL fields */ #define CLK_SEL_MSK GENMASK(2, 0) @@ -325,9 +346,9 @@ static inline u32 geni_se_read_proto(struct geni_se *se) { u32 val; - val = readl_relaxed(se->base + GENI_FW_REVISION_RO); + val = readl_relaxed(se->base + SE_GENI_FW_REVISION_RO); - return (val & FW_REV_PROTOCOL_MSK) >> FW_REV_PROTOCOL_SHFT; + return FIELD_GET(FW_REV_PROTOCOL_MSK, val); } /** @@ -531,5 +552,7 @@ void geni_icc_set_tag(struct geni_se *se, u32 tag); int geni_icc_enable(struct geni_se *se); int geni_icc_disable(struct geni_se *se); + +int geni_load_se_firmware(struct geni_se *se, enum geni_se_protocol_type protocol); #endif #endif diff --git a/include/linux/soc/qcom/qup-fw-load.h b/include/linux/soc/qcom/qup-fw-load.h new file mode 100644 index 0000000000000..08d8a22ae5141 --- /dev/null +++ b/include/linux/soc/qcom/qup-fw-load.h @@ -0,0 +1,89 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved. + */ +#ifndef _LINUX_QCOM_QUP_FW_LOAD +#define _LINUX_QCOM_QUP_FW_LOAD + +#include + +/*Magic numbers*/ +#define MAGIC_NUM_SE 0x57464553 + +#define MAX_GENI_CFG_RAMn_CNT 455 + +#define MI_PBT_NON_PAGED_SEGMENT 0x0 +#define MI_PBT_HASH_SEGMENT 0x2 +#define MI_PBT_NOTUSED_SEGMENT 0x3 +#define MI_PBT_SHARED_SEGMENT 0x4 + +#define MI_PBT_FLAG_PAGE_MODE BIT(20) +#define MI_PBT_FLAG_SEGMENT_TYPE GENMASK(26, 24) +#define MI_PBT_FLAG_ACCESS_TYPE GENMASK(23, 21) + +#define MI_PBT_PAGE_MODE_VALUE(x) FIELD_GET(MI_PBT_FLAG_PAGE_MODE, x) + +#define MI_PBT_SEGMENT_TYPE_VALUE(x) FIELD_GET(MI_PBT_FLAG_SEGMENT_TYPE, x) + +#define MI_PBT_ACCESS_TYPE_VALUE(x) FIELD_GET(MI_PBT_FLAG_ACCESS_TYPE, x) + +#define M_COMMON_GENI_M_IRQ_EN (GENMASK(6, 1) | \ + M_IO_DATA_DEASSERT_EN | \ + M_IO_DATA_ASSERT_EN | M_RX_FIFO_RD_ERR_EN | \ + M_RX_FIFO_WR_ERR_EN | M_TX_FIFO_RD_ERR_EN | \ + M_TX_FIFO_WR_ERR_EN) + +/* DMA_TX/RX_IRQ_EN fields */ +#define DMA_DONE_EN BIT(0) +#define SBE_EN BIT(2) +#define RESET_DONE_EN BIT(3) +#define FLUSH_DONE_EN BIT(4) + +/* GENI_CLK_CTRL fields */ +#define SER_CLK_SEL BIT(0) + +/* GENI_DMA_IF_EN fields */ +#define DMA_IF_EN BIT(0) + +#define QUPV3_COMMON_CFG 0x120 +#define FAST_SWITCH_TO_HIGH_DISABLE BIT(0) + +#define QUPV3_SE_AHB_M_CFG 0x118 +#define AHB_M_CLK_CGC_ON BIT(0) + +#define QUPV3_COMMON_CGC_CTRL 0x21C +#define COMMON_CSR_SLV_CLK_CGC_ON BIT(0) + +/* access ports */ +#define geni_setbits32(_addr, _v) writel_relaxed(readl_relaxed(_addr) | (_v), _addr) +#define geni_clrbits32(_addr, _v) writel_relaxed(readl_relaxed(_addr) & ~(_v), _addr) + +/** + * struct elf_se_hdr - firmware configurations + * + * @magic: set to 'SEFW' + * @version: A 32-bit value indicating the structure’s version number + * @core_version: QUPV3_HW_VERSION + * @serial_protocol: Programmed into GENI_FW_REVISION + * @fw_version: Programmed into GENI_FW_REVISION + * @cfg_version: Programmed into GENI_INIT_CFG_REVISION + * @fw_size_in_items: Number of (uint32_t) GENI_FW_RAM words + * @fw_offset: Byte offset of GENI_FW_RAM array + * @cfg_items_size: Number of GENI_FW_CFG index/value pairs + * @cfg_idx_offset: Byte offset of GENI_FW_CFG index array + * @cfg_val_offset: Byte offset of GENI_FW_CFG values array + */ +struct elf_se_hdr { + u32 magic; + u32 version; + u32 core_version; + u16 serial_protocol; + u16 fw_version; + u16 cfg_version; + u16 fw_size_in_items; + u16 fw_offset; + u16 cfg_items_size; + u16 cfg_idx_offset; + u16 cfg_val_offset; +}; +#endif /* _LINUX_QCOM_QUP_FW_LOAD */ diff --git a/qcom-next/merge.log b/qcom-next/merge.log new file mode 100644 index 0000000000000..5441ecf0e8e93 --- /dev/null +++ b/qcom-next/merge.log @@ -0,0 +1,435 @@ +Verified existence of local and remote repos: Success +/local/mnt/workspace/automerge/actions-runner/_work/kernel-automation/kernel-automation/kernel-topics /local/mnt/workspace/automerge/actions-runner/_work/kernel-automation/kernel-automation/kernel-topics +Reuse-Recorded-Resolution: Disabled +Local tree is clean +Removing old remotes ... +The remote origin https://github.com/qualcomm-linux/kernel-topics.git is no longer tracked. +Delete it [Y/n]? Done, removed 1 old remote(s). +Adding new remotes... +Adding remote baseline git@github.com:qualcomm-linux/kernel.git qcom-next-staging +Updating baseline +Adding remote tech/bsp/clk git@github.com:qualcomm-linux/kernel-topics.git tech/bsp/clk +Updating tech/bsp/clk +Adding remote tech/bsp/interconnect git@github.com:qualcomm-linux/kernel-topics.git tech/bsp/interconnect +Updating tech/bsp/interconnect +Adding remote tech/mem/secure-buffer git@github.com:qualcomm-linux/kernel-topics.git tech/mem/secure-buffer +Updating tech/mem/secure-buffer +Adding remote tech/security/firmware-smc git@github.com:qualcomm-linux/kernel-topics.git tech/security/firmware-smc +Updating tech/security/firmware-smc +Adding remote tech/bsp/soc-infra git@github.com:qualcomm-linux/kernel-topics.git tech/bsp/soc-infra +Updating tech/bsp/soc-infra +Adding remote tech/debug/soc git@github.com:qualcomm-linux/kernel-topics.git tech/debug/soc +Updating tech/debug/soc +Adding remote tech/bsp/pinctrl git@github.com:qualcomm-linux/kernel-topics.git tech/bsp/pinctrl +Updating tech/bsp/pinctrl +Adding remote tech/bsp/remoteproc git@github.com:qualcomm-linux/kernel-topics.git tech/bsp/remoteproc +Updating tech/bsp/remoteproc +Adding remote tech/bus/peripherals git@github.com:qualcomm-linux/kernel-topics.git tech/bus/peripherals +Updating tech/bus/peripherals +Adding remote tech/bus/pci/all git@github.com:qualcomm-linux/kernel-topics.git tech/bus/pci/all +Updating tech/bus/pci/all +Adding remote tech/bus/pci/mhi git@github.com:qualcomm-linux/kernel-topics.git tech/bus/pci/mhi +Updating tech/bus/pci/mhi +Adding remote tech/bus/pci/phy git@github.com:qualcomm-linux/kernel-topics.git tech/bus/pci/phy +Updating tech/bus/pci/phy +Adding remote tech/bus/pci/pwrctl git@github.com:qualcomm-linux/kernel-topics.git tech/bus/pci/pwrctl +Updating tech/bus/pci/pwrctl +Adding remote tech/bus/usb/dwc git@github.com:qualcomm-linux/kernel-topics.git tech/bus/usb/dwc +Updating tech/bus/usb/dwc +Adding remote tech/bus/usb/gadget git@github.com:qualcomm-linux/kernel-topics.git tech/bus/usb/gadget +Updating tech/bus/usb/gadget +Adding remote tech/bus/usb/phy git@github.com:qualcomm-linux/kernel-topics.git tech/bus/usb/phy +Updating tech/bus/usb/phy +Adding remote tech/debug/eud git@github.com:qualcomm-linux/kernel-topics.git tech/debug/eud +Updating tech/debug/eud +Adding remote tech/debug/hwtracing git@github.com:qualcomm-linux/kernel-topics.git tech/debug/hwtracing +Updating tech/debug/hwtracing +Adding remote tech/debug/rdbg git@github.com:qualcomm-linux/kernel-topics.git tech/debug/rdbg +Updating tech/debug/rdbg +Adding remote tech/pmic/backlight git@github.com:qualcomm-linux/kernel-topics.git tech/pmic/backlight +Updating tech/pmic/backlight +Adding remote tech/pmic/mfd git@github.com:qualcomm-linux/kernel-topics.git tech/pmic/mfd +Updating tech/pmic/mfd +Adding remote tech/pmic/misc git@github.com:qualcomm-linux/kernel-topics.git tech/pmic/misc +Updating tech/pmic/misc +Adding remote tech/pmic/regulator git@github.com:qualcomm-linux/kernel-topics.git tech/pmic/regulator +Updating tech/pmic/regulator +Adding remote tech/pmic/supply git@github.com:qualcomm-linux/kernel-topics.git tech/pmic/supply +Updating tech/pmic/supply +Adding remote tech/mem/dma-buf git@github.com:qualcomm-linux/kernel-topics.git tech/mem/dma-buf +Updating tech/mem/dma-buf +Adding remote tech/mem/iommu git@github.com:qualcomm-linux/kernel-topics.git tech/mem/iommu +Updating tech/mem/iommu +Adding remote tech/mm/audio/all git@github.com:qualcomm-linux/kernel-topics.git tech/mm/audio/all +Updating tech/mm/audio/all +Adding remote tech/mm/audio/soundwire git@github.com:qualcomm-linux/kernel-topics.git tech/mm/audio/soundwire +Updating tech/mm/audio/soundwire +Adding remote tech/mm/camss git@github.com:qualcomm-linux/kernel-topics.git tech/mm/camss +Updating tech/mm/camss +Adding remote tech/mm/drm git@github.com:qualcomm-linux/kernel-topics.git tech/mm/drm +Updating tech/mm/drm +Adding remote tech/mm/fastrpc git@github.com:qualcomm-linux/kernel-topics.git tech/mm/fastrpc +Updating tech/mm/fastrpc +Adding remote tech/mm/phy git@github.com:qualcomm-linux/kernel-topics.git tech/mm/phy +Updating tech/mm/phy +Adding remote tech/mm/video git@github.com:qualcomm-linux/kernel-topics.git tech/mm/video +Updating tech/mm/video +Adding remote tech/mproc/rpmsg git@github.com:qualcomm-linux/kernel-topics.git tech/mproc/rpmsg +Updating tech/mproc/rpmsg +Adding remote tech/mproc/qmi git@github.com:qualcomm-linux/kernel-topics.git tech/mproc/qmi +Updating tech/mproc/qmi +Adding remote tech/net/ath git@github.com:qualcomm-linux/kernel-topics.git tech/net/ath +Updating tech/net/ath +Adding remote tech/net/eth git@github.com:qualcomm-linux/kernel-topics.git tech/net/eth +Updating tech/net/eth +Adding remote tech/net/rmnet git@github.com:qualcomm-linux/kernel-topics.git tech/net/rmnet +Updating tech/net/rmnet +Adding remote tech/net/qrtr git@github.com:qualcomm-linux/kernel-topics.git tech/net/qrtr +Updating tech/net/qrtr +Adding remote tech/net/phy git@github.com:qualcomm-linux/kernel-topics.git tech/net/phy +Updating tech/net/phy +Adding remote tech/net/bluetooth git@github.com:qualcomm-linux/kernel-topics.git tech/net/bluetooth +Updating tech/net/bluetooth +Adding remote tech/pm/opp git@github.com:qualcomm-linux/kernel-topics.git tech/pm/opp +Updating tech/pm/opp +Adding remote tech/pm/pmdomain git@github.com:qualcomm-linux/kernel-topics.git tech/pm/pmdomain +Updating tech/pm/pmdomain +Adding remote tech/pm/power git@github.com:qualcomm-linux/kernel-topics.git tech/pm/power +Updating tech/pm/power +Adding remote tech/pm/thermal git@github.com:qualcomm-linux/kernel-topics.git tech/pm/thermal +Updating tech/pm/thermal +Adding remote tech/security/crypto git@github.com:qualcomm-linux/kernel-topics.git tech/security/crypto +Updating tech/security/crypto +Adding remote tech/security/fscrypt git@github.com:qualcomm-linux/kernel-topics.git tech/security/fscrypt +Updating tech/security/fscrypt +Adding remote tech/security/ice git@github.com:qualcomm-linux/kernel-topics.git tech/security/ice +Updating tech/security/ice +Adding remote tech/storage/nvmem git@github.com:qualcomm-linux/kernel-topics.git tech/storage/nvmem +Updating tech/storage/nvmem +Adding remote tech/storage/phy git@github.com:qualcomm-linux/kernel-topics.git tech/storage/phy +Updating tech/storage/phy +Adding remote tech/storage/all git@github.com:qualcomm-linux/kernel-topics.git tech/storage/all +Updating tech/storage/all +Adding remote tech/virt/gunyah git@github.com:qualcomm-linux/kernel-topics.git tech/virt/gunyah +Updating tech/virt/gunyah +Adding remote tech/all/workaround git@github.com:qualcomm-linux/kernel-topics.git tech/all/workaround +Updating tech/all/workaround +Adding remote tech/all/dt/qcs6490 git@github.com:qualcomm-linux/kernel-topics.git tech/all/dt/qcs6490 +Updating tech/all/dt/qcs6490 +Adding remote tech/all/dt/qcs9100 git@github.com:qualcomm-linux/kernel-topics.git tech/all/dt/qcs9100 +Updating tech/all/dt/qcs9100 +Adding remote tech/all/dt/qcs8300 git@github.com:qualcomm-linux/kernel-topics.git tech/all/dt/qcs8300 +Updating tech/all/dt/qcs8300 +Adding remote tech/all/dt/qcs615 git@github.com:qualcomm-linux/kernel-topics.git tech/all/dt/qcs615 +Updating tech/all/dt/qcs615 +Adding remote tech/all/config git@github.com:qualcomm-linux/kernel-topics.git tech/all/config +Updating tech/all/config +Adding remote tech/mm/gpu git@github.com:qualcomm-linux/kernel-topics.git tech/mm/gpu +Updating tech/mm/gpu +Done, added 60 new remote(s). +Updating the remotes ... +Updating tech/bsp/clk +tech/bsp/clk has changed. +Updating tech/bsp/interconnect +tech/bsp/interconnect has changed. +Updating tech/mem/secure-buffer +tech/mem/secure-buffer has changed. +Updating tech/security/firmware-smc +tech/security/firmware-smc has changed. +Updating tech/bsp/soc-infra +tech/bsp/soc-infra has changed. +Updating tech/debug/soc +tech/debug/soc has changed. +Updating tech/bsp/pinctrl +tech/bsp/pinctrl has changed. +Updating tech/bsp/remoteproc +tech/bsp/remoteproc has changed. +Updating tech/bus/peripherals +tech/bus/peripherals has changed. +Updating tech/bus/pci/all +tech/bus/pci/all has changed. +Updating tech/bus/pci/mhi +tech/bus/pci/mhi has changed. +Updating tech/bus/pci/phy +tech/bus/pci/phy has changed. +Updating tech/bus/pci/pwrctl +tech/bus/pci/pwrctl has changed. +Updating tech/bus/usb/dwc +tech/bus/usb/dwc has changed. +Updating tech/bus/usb/gadget +tech/bus/usb/gadget has changed. +Updating tech/bus/usb/phy +tech/bus/usb/phy has changed. +Updating tech/debug/eud +tech/debug/eud has changed. +Updating tech/debug/hwtracing +tech/debug/hwtracing has changed. +Updating tech/debug/rdbg +tech/debug/rdbg has changed. +Updating tech/pmic/backlight +tech/pmic/backlight has changed. +Updating tech/pmic/mfd +tech/pmic/mfd has changed. +Updating tech/pmic/misc +tech/pmic/misc has changed. +Updating tech/pmic/regulator +tech/pmic/regulator has changed. +Updating tech/pmic/supply +tech/pmic/supply has changed. +Updating tech/mem/dma-buf +tech/mem/dma-buf has changed. +Updating tech/mem/iommu +tech/mem/iommu has changed. +Updating tech/mm/audio/all +tech/mm/audio/all has changed. +Updating tech/mm/audio/soundwire +tech/mm/audio/soundwire has changed. +Updating tech/mm/camss +tech/mm/camss has changed. +Updating tech/mm/drm +tech/mm/drm has changed. +Updating tech/mm/fastrpc +tech/mm/fastrpc has changed. +Updating tech/mm/phy +tech/mm/phy has changed. +Updating tech/mm/video +tech/mm/video has changed. +Updating tech/mproc/rpmsg +tech/mproc/rpmsg has changed. +Updating tech/mproc/qmi +tech/mproc/qmi has changed. +Updating tech/net/ath +tech/net/ath has changed. +Updating tech/net/eth +tech/net/eth has changed. +Updating tech/net/rmnet +tech/net/rmnet has changed. +Updating tech/net/qrtr +tech/net/qrtr has changed. +Updating tech/net/phy +tech/net/phy has changed. +Updating tech/net/bluetooth +tech/net/bluetooth has changed. +Updating tech/pm/opp +tech/pm/opp has changed. +Updating tech/pm/pmdomain +tech/pm/pmdomain has changed. +Updating tech/pm/power +tech/pm/power has changed. +Updating tech/pm/thermal +tech/pm/thermal has changed. +Updating tech/security/crypto +tech/security/crypto has changed. +Updating tech/security/fscrypt +tech/security/fscrypt has changed. +Updating tech/security/ice +tech/security/ice has changed. +Updating tech/storage/nvmem +tech/storage/nvmem has changed. +Updating tech/storage/phy +tech/storage/phy has changed. +Updating tech/storage/all +tech/storage/all has changed. +Updating tech/virt/gunyah +tech/virt/gunyah has changed. +Updating tech/all/workaround +tech/all/workaround has changed. +Updating tech/all/dt/qcs6490 +tech/all/dt/qcs6490 has changed. +Updating tech/all/dt/qcs9100 +tech/all/dt/qcs9100 has changed. +Updating tech/all/dt/qcs8300 +tech/all/dt/qcs8300 has changed. +Updating tech/all/dt/qcs615 +tech/all/dt/qcs615 has changed. +Updating tech/all/config +tech/all/config has changed. +Updating tech/mm/gpu +tech/mm/gpu has changed. +Done, updated 59 remote(s). +Updating baseline ... +Fetching baseline +X11 forwarding request failed on channel 0 +latest tag/id is aa3bd00967bd7929f7fe8af72bbc27e428fd2dd4 +Done, updated baseline. +Latest tag is aa3bd00967bd7929f7fe8af72bbc27e428fd2dd4 +Create a new integration branch based on aa3bd00967bd7929f7fe8af72bbc27e428fd2dd4 +Merging topic branches... +------------------------------------------ + ** Merging topic branch: tech/bsp/clk/tech/bsp/clk +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/bsp/interconnect/tech/bsp/interconnect +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/mem/secure-buffer/tech/mem/secure-buffer +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/security/firmware-smc/tech/security/firmware-smc +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/bsp/soc-infra/tech/bsp/soc-infra +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/debug/soc/tech/debug/soc +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/bsp/pinctrl/tech/bsp/pinctrl +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/bsp/remoteproc/tech/bsp/remoteproc +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/bus/peripherals/tech/bus/peripherals +Merge successful : tech/bus/peripherals : ed0f1f841818b59155935b6047ac1f5b3b5a1e57 : 5 +------------------------------------------ + ** Merging topic branch: tech/bus/pci/all/tech/bus/pci/all +Merge successful : tech/bus/pci/all : 5159ecf66111209bb6561b6897edb53ada242ca1 : 8 +------------------------------------------ + ** Merging topic branch: tech/bus/pci/mhi/tech/bus/pci/mhi +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/bus/pci/phy/tech/bus/pci/phy +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/bus/pci/pwrctl/tech/bus/pci/pwrctl +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/bus/usb/dwc/tech/bus/usb/dwc +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/bus/usb/gadget/tech/bus/usb/gadget +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/bus/usb/phy/tech/bus/usb/phy +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/debug/eud/tech/debug/eud +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/debug/hwtracing/tech/debug/hwtracing +Merge successful : tech/debug/hwtracing : efd272ea9bdccfbd168fe9ecf8f42672c0c197a2 : 14 +------------------------------------------ + ** Merging topic branch: tech/debug/rdbg/tech/debug/rdbg +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/pmic/backlight/tech/pmic/backlight +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/pmic/mfd/tech/pmic/mfd +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/pmic/misc/tech/pmic/misc +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/pmic/regulator/tech/pmic/regulator +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/pmic/supply/tech/pmic/supply +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/mem/dma-buf/tech/mem/dma-buf +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/mem/iommu/tech/mem/iommu +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/mm/audio/all/tech/mm/audio/all +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/mm/audio/soundwire/tech/mm/audio/soundwire +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/mm/camss/tech/mm/camss +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/mm/drm/tech/mm/drm +Merge successful : tech/mm/drm : 7c42242f76761d3fd7ecbe99a1a8036908906093 : 1 +------------------------------------------ + ** Merging topic branch: tech/mm/fastrpc/tech/mm/fastrpc +Merge successful : tech/mm/fastrpc : 5a94c05e12cbc5cecb3a039d67c51bd8aff0ecec : 5 +------------------------------------------ + ** Merging topic branch: tech/mm/phy/tech/mm/phy +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/mm/video/tech/mm/video +Merge successful : tech/mm/video : 8e7bd4865e2a6767264326990b942dc8c61bc40d : 26 +------------------------------------------ + ** Merging topic branch: tech/mproc/rpmsg/tech/mproc/rpmsg +Merge successful : tech/mproc/rpmsg : adf3d0ae30d0e39e7db861824b705b7f7a3040bc : 1 +------------------------------------------ + ** Merging topic branch: tech/mproc/qmi/tech/mproc/qmi +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/net/ath/tech/net/ath +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/net/eth/tech/net/eth +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/net/rmnet/tech/net/rmnet +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/net/qrtr/tech/net/qrtr +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/net/phy/tech/net/phy +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/net/bluetooth/tech/net/bluetooth +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/pm/opp/tech/pm/opp +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/pm/pmdomain/tech/pm/pmdomain +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/pm/power/tech/pm/power +Merge successful : tech/pm/power : 1eeed9b4e31525fcaa3b16365aa32c5d0ecb5010 : 1 +------------------------------------------ + ** Merging topic branch: tech/pm/thermal/tech/pm/thermal +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/security/crypto/tech/security/crypto +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/security/fscrypt/tech/security/fscrypt +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/security/ice/tech/security/ice +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/storage/nvmem/tech/storage/nvmem +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/storage/phy/tech/storage/phy +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/storage/all/tech/storage/all +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/virt/gunyah/tech/virt/gunyah +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/all/workaround/tech/all/workaround +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/all/dt/qcs6490/tech/all/dt/qcs6490 +Merge successful : tech/all/dt/qcs6490 : e9c1cced62d4d2a64bdc5b56329d3741733d53d1 : 11 +------------------------------------------ + ** Merging topic branch: tech/all/dt/qcs9100/tech/all/dt/qcs9100 +Merge successful : tech/all/dt/qcs9100 : 31667be7ef83c26a6aad5fa41ac63900c6796db5 : 7 +------------------------------------------ + ** Merging topic branch: tech/all/dt/qcs8300/tech/all/dt/qcs8300 +Nothing to merge: Already up to date. +------------------------------------------ + ** Merging topic branch: tech/all/dt/qcs615/tech/all/dt/qcs615 +Merge successful : tech/all/dt/qcs615 : 7593857604f2c674328e1103ec354fee642295b0 : 11 +------------------------------------------ + ** Merging topic branch: tech/all/config/tech/all/config +Merge successful : tech/all/config : dd11b10685e12626359930e4d606a7fc25824014 : 1 +------------------------------------------ + ** Merging topic branch: tech/mm/gpu/tech/mm/gpu +Nothing to merge: Already up to date. +Done, merged 12 topic(s). diff --git a/qcom-next/topic_SHA1 b/qcom-next/topic_SHA1 new file mode 100644 index 0000000000000..60302102914f0 --- /dev/null +++ b/qcom-next/topic_SHA1 @@ -0,0 +1,14 @@ +Name SHA Commits +------------------------------------------------------------------------------------ +tech/bus/peripherals ed0f1f841818b59155935b6047ac1f5b3b5a1e57 5 +tech/bus/pci/all 5159ecf66111209bb6561b6897edb53ada242ca1 8 +tech/debug/hwtracing efd272ea9bdccfbd168fe9ecf8f42672c0c197a2 14 +tech/mm/drm 7c42242f76761d3fd7ecbe99a1a8036908906093 1 +tech/mm/fastrpc 5a94c05e12cbc5cecb3a039d67c51bd8aff0ecec 5 +tech/mm/video 8e7bd4865e2a6767264326990b942dc8c61bc40d 26 +tech/mproc/rpmsg adf3d0ae30d0e39e7db861824b705b7f7a3040bc 1 +tech/pm/power 1eeed9b4e31525fcaa3b16365aa32c5d0ecb5010 1 +tech/all/dt/qcs6490 e9c1cced62d4d2a64bdc5b56329d3741733d53d1 11 +tech/all/dt/qcs9100 31667be7ef83c26a6aad5fa41ac63900c6796db5 7 +tech/all/dt/qcs615 7593857604f2c674328e1103ec354fee642295b0 11 +tech/all/config dd11b10685e12626359930e4d606a7fc25824014 1