Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'rproc-v5.18' of git://git.kernel.org/pub/scm/linux/kernel/git/remoteproc/linux

Pull remoteproc updates from Bjorn Andersson:
"In the remoteproc core, it's now possible to mark the sysfs attributes
read only on a per-instance basis, which is then used by the TI wkup
M3 driver.

Also, the rproc_shutdown() interface propagates errors to the caller
and an array underflow is fixed in the debugfs interface. The
rproc_da_to_va() API is moved to the public API to allow e.g. child
rpmsg devices to acquire pointers to memory shared with the remote
processor.

The TI K3 R5F and DSP drivers gains support for attaching to instances
already started by the bootloader, aka IPC-only mode.

The Mediatek remoteproc driver gains support for the MT8186 SCP. The
driver's probe function is reordered and moved to use the devres
version of rproc_alloc() to save a few gotos. The driver's probe
function is also transitioned to use dev_err_probe() to provide better
debug support.

Support for the Qualcomm SC7280 Wireless Subsystem (WPSS) is
introduced. The Hexagon based remoteproc drivers gains support for
voting for interconnect bandwidth during launch of the remote
processor. The modem subsystem (MSS) driver gains support for probing
the BAM-DMUX driver, which provides the network interface towards the
modem on a set of older Qualcomm platforms. In addition a number a bug
fixes are introduces in the Qualcomm drivers.

Lastly Qualcomm ADSP DeviceTree binding is converted to YAML format,
to allow validation of DeviceTree source files"

* tag 'rproc-v5.18' of git://git.kernel.org/pub/scm/linux/kernel/git/remoteproc/linux: (22 commits)
remoteproc: qcom_q6v5_mss: Create platform device for BAM-DMUX
remoteproc: qcom: q6v5_wpss: Add support for sc7280 WPSS
dt-bindings: remoteproc: qcom: Add SC7280 WPSS support
dt-bindings: remoteproc: qcom: adsp: Convert binding to YAML
remoteproc: k3-dsp: Add support for IPC-only mode for all K3 DSPs
remoteproc: k3-dsp: Refactor mbox request code in start
remoteproc: k3-r5: Add support for IPC-only mode for all R5Fs
remoteproc: k3-r5: Refactor mbox request code in start
remoteproc: Change rproc_shutdown() to return a status
remoteproc: qcom: q6v5: Add interconnect path proxy vote
remoteproc: mediatek: Support mt8186 scp
dt-bindings: remoteproc: mediatek: Add binding for mt8186 scp
remoteproc: qcom_q6v5_mss: Fix some leaks in q6v5_alloc_memory_region
remoteproc: qcom_wcnss: Add missing of_node_put() in wcnss_alloc_memory_region
remoteproc: qcom: Fix missing of_node_put in adsp_alloc_memory_region
remoteproc: move rproc_da_to_va declaration to remoteproc.h
remoteproc: wkup_m3: Set sysfs_read_only flag
remoteproc: Introduce sysfs_read_only flag
remoteproc: Fix count check in rproc_coredump_write()
remoteproc: mtk_scp: Use dev_err_probe() where possible
...

+1335 -310
+1
Documentation/devicetree/bindings/remoteproc/mtk,scp.yaml
··· 17 17 compatible: 18 18 enum: 19 19 - mediatek,mt8183-scp 20 + - mediatek,mt8186-scp 20 21 - mediatek,mt8192-scp 21 22 - mediatek,mt8195-scp 22 23
-140
Documentation/devicetree/bindings/remoteproc/qcom,hexagon-v56.txt
··· 1 - Qualcomm Technology Inc. Hexagon v56 Peripheral Image Loader 2 - 3 - This document defines the binding for a component that loads and boots firmware 4 - on the Qualcomm Technology Inc. Hexagon v56 core. 5 - 6 - - compatible: 7 - Usage: required 8 - Value type: <string> 9 - Definition: must be one of: 10 - "qcom,qcs404-cdsp-pil", 11 - "qcom,sdm845-adsp-pil" 12 - 13 - - reg: 14 - Usage: required 15 - Value type: <prop-encoded-array> 16 - Definition: must specify the base address and size of the qdsp6ss register 17 - 18 - - interrupts-extended: 19 - Usage: required 20 - Value type: <prop-encoded-array> 21 - Definition: must list the watchdog, fatal IRQs ready, handover and 22 - stop-ack IRQs 23 - 24 - - interrupt-names: 25 - Usage: required 26 - Value type: <stringlist> 27 - Definition: must be "wdog", "fatal", "ready", "handover", "stop-ack" 28 - 29 - - clocks: 30 - Usage: required 31 - Value type: <prop-encoded-array> 32 - Definition: List of phandles and clock specifier pairs for the Hexagon, 33 - per clock-names below. 34 - 35 - - clock-names: 36 - Usage: required for SDM845 ADSP 37 - Value type: <stringlist> 38 - Definition: List of clock input name strings sorted in the same 39 - order as the clocks property. Definition must have 40 - "xo", "sway_cbcr", "lpass_ahbs_aon_cbcr", 41 - "lpass_ahbm_aon_cbcr", "qdsp6ss_xo", "qdsp6ss_sleep" 42 - and "qdsp6ss_core". 43 - 44 - - clock-names: 45 - Usage: required for QCS404 CDSP 46 - Value type: <stringlist> 47 - Definition: List of clock input name strings sorted in the same 48 - order as the clocks property. Definition must have 49 - "xo", "sway", "tbu", "bimc", "ahb_aon", "q6ss_slave", 50 - "q6ss_master", "q6_axim". 51 - 52 - - power-domains: 53 - Usage: required 54 - Value type: <phandle> 55 - Definition: reference to cx power domain node. 56 - 57 - - resets: 58 - Usage: required 59 - Value type: <phandle> 60 - Definition: reference to the list of resets for the Hexagon. 61 - 62 - - reset-names: 63 - Usage: required for SDM845 ADSP 64 - Value type: <stringlist> 65 - Definition: must be "pdc_sync" and "cc_lpass" 66 - 67 - - reset-names: 68 - Usage: required for QCS404 CDSP 69 - Value type: <stringlist> 70 - Definition: must be "restart" 71 - 72 - - qcom,halt-regs: 73 - Usage: required 74 - Value type: <prop-encoded-array> 75 - Definition: a phandle reference to a syscon representing TCSR followed 76 - by the offset within syscon for Hexagon halt register. 77 - 78 - - memory-region: 79 - Usage: required 80 - Value type: <phandle> 81 - Definition: reference to the reserved-memory for the firmware 82 - 83 - - qcom,smem-states: 84 - Usage: required 85 - Value type: <phandle> 86 - Definition: reference to the smem state for requesting the Hexagon to 87 - shut down 88 - 89 - - qcom,smem-state-names: 90 - Usage: required 91 - Value type: <stringlist> 92 - Definition: must be "stop" 93 - 94 - 95 - = SUBNODES 96 - The adsp node may have an subnode named "glink-edge" that describes the 97 - communication edge, channels and devices related to the Hexagon. 98 - See ../soc/qcom/qcom,glink.txt for details on how to describe these. 99 - 100 - = EXAMPLE 101 - The following example describes the resources needed to boot control the 102 - ADSP, as it is found on SDM845 boards. 103 - 104 - remoteproc@17300000 { 105 - compatible = "qcom,sdm845-adsp-pil"; 106 - reg = <0x17300000 0x40c>; 107 - 108 - interrupts-extended = <&intc GIC_SPI 162 IRQ_TYPE_EDGE_RISING>, 109 - <&adsp_smp2p_in 0 IRQ_TYPE_EDGE_RISING>, 110 - <&adsp_smp2p_in 1 IRQ_TYPE_EDGE_RISING>, 111 - <&adsp_smp2p_in 2 IRQ_TYPE_EDGE_RISING>, 112 - <&adsp_smp2p_in 3 IRQ_TYPE_EDGE_RISING>; 113 - interrupt-names = "wdog", "fatal", "ready", 114 - "handover", "stop-ack"; 115 - 116 - clocks = <&rpmhcc RPMH_CXO_CLK>, 117 - <&gcc GCC_LPASS_SWAY_CLK>, 118 - <&lpasscc LPASS_Q6SS_AHBS_AON_CLK>, 119 - <&lpasscc LPASS_Q6SS_AHBM_AON_CLK>, 120 - <&lpasscc LPASS_QDSP6SS_XO_CLK>, 121 - <&lpasscc LPASS_QDSP6SS_SLEEP_CLK>, 122 - <&lpasscc LPASS_QDSP6SS_CORE_CLK>; 123 - clock-names = "xo", "sway_cbcr", 124 - "lpass_ahbs_aon_cbcr", 125 - "lpass_ahbm_aon_cbcr", "qdsp6ss_xo", 126 - "qdsp6ss_sleep", "qdsp6ss_core"; 127 - 128 - power-domains = <&rpmhpd SDM845_CX>; 129 - 130 - resets = <&pdc_reset PDC_AUDIO_SYNC_RESET>, 131 - <&aoss_reset AOSS_CC_LPASS_RESTART>; 132 - reset-names = "pdc_sync", "cc_lpass"; 133 - 134 - qcom,halt-regs = <&tcsr_mutex_regs 0x22000>; 135 - 136 - memory-region = <&pil_adsp_mem>; 137 - 138 - qcom,smem-states = <&adsp_smp2p_out 0>; 139 - qcom,smem-state-names = "stop"; 140 - };
+161
Documentation/devicetree/bindings/remoteproc/qcom,qcs404-cdsp-pil.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/remoteproc/qcom,qcs404-cdsp-pil.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Qualcomm QCS404 CDSP Peripheral Image Loader 8 + 9 + maintainers: 10 + - Bjorn Andersson <bjorn.andersson@linaro.org> 11 + 12 + description: 13 + This document defines the binding for a component that loads and boots firmware 14 + on the Qualcomm Technology Inc. CDSP (Compute DSP). 15 + 16 + properties: 17 + compatible: 18 + enum: 19 + - qcom,qcs404-cdsp-pil 20 + 21 + reg: 22 + maxItems: 1 23 + description: 24 + The base address and size of the qdsp6ss register 25 + 26 + interrupts: 27 + items: 28 + - description: Watchdog interrupt 29 + - description: Fatal interrupt 30 + - description: Ready interrupt 31 + - description: Handover interrupt 32 + - description: Stop acknowledge interrupt 33 + 34 + interrupt-names: 35 + items: 36 + - const: wdog 37 + - const: fatal 38 + - const: ready 39 + - const: handover 40 + - const: stop-ack 41 + 42 + clocks: 43 + items: 44 + - description: XO clock 45 + - description: SWAY clock 46 + - description: TBU clock 47 + - description: BIMC clock 48 + - description: AHB AON clock 49 + - description: Q6SS SLAVE clock 50 + - description: Q6SS MASTER clock 51 + - description: Q6 AXIM clock 52 + 53 + clock-names: 54 + items: 55 + - const: xo 56 + - const: sway 57 + - const: tbu 58 + - const: bimc 59 + - const: ahb_aon 60 + - const: q6ss_slave 61 + - const: q6ss_master 62 + - const: q6_axim 63 + 64 + power-domains: 65 + items: 66 + - description: CX power domain 67 + 68 + resets: 69 + items: 70 + - description: AOSS restart 71 + 72 + reset-names: 73 + items: 74 + - const: restart 75 + 76 + memory-region: 77 + maxItems: 1 78 + description: Reference to the reserved-memory for the Hexagon core 79 + 80 + qcom,halt-regs: 81 + $ref: /schemas/types.yaml#/definitions/phandle-array 82 + description: 83 + Phandle reference to a syscon representing TCSR followed by the 84 + three offsets within syscon for q6, modem and nc halt registers. 85 + 86 + qcom,smem-states: 87 + $ref: /schemas/types.yaml#/definitions/phandle-array 88 + description: States used by the AP to signal the Hexagon core 89 + items: 90 + - description: Stop the modem 91 + 92 + qcom,smem-state-names: 93 + $ref: /schemas/types.yaml#/definitions/string 94 + description: The names of the state bits used for SMP2P output 95 + items: 96 + - const: stop 97 + 98 + required: 99 + - compatible 100 + - reg 101 + - interrupts 102 + - interrupt-names 103 + - clocks 104 + - clock-names 105 + - power-domains 106 + - resets 107 + - reset-names 108 + - qcom,halt-regs 109 + - memory-region 110 + - qcom,smem-states 111 + - qcom,smem-state-names 112 + 113 + additionalProperties: false 114 + 115 + examples: 116 + - | 117 + #include <dt-bindings/interrupt-controller/arm-gic.h> 118 + #include <dt-bindings/clock/qcom,gcc-qcs404.h> 119 + #include <dt-bindings/power/qcom-rpmpd.h> 120 + #include <dt-bindings/clock/qcom,turingcc-qcs404.h> 121 + remoteproc@b00000 { 122 + compatible = "qcom,qcs404-cdsp-pil"; 123 + reg = <0x00b00000 0x4040>; 124 + 125 + interrupts-extended = <&intc GIC_SPI 229 IRQ_TYPE_EDGE_RISING>, 126 + <&cdsp_smp2p_in 0 IRQ_TYPE_EDGE_RISING>, 127 + <&cdsp_smp2p_in 1 IRQ_TYPE_EDGE_RISING>, 128 + <&cdsp_smp2p_in 2 IRQ_TYPE_EDGE_RISING>, 129 + <&cdsp_smp2p_in 3 IRQ_TYPE_EDGE_RISING>; 130 + interrupt-names = "wdog", "fatal", "ready", 131 + "handover", "stop-ack"; 132 + 133 + clocks = <&xo_board>, 134 + <&gcc GCC_CDSP_CFG_AHB_CLK>, 135 + <&gcc GCC_CDSP_TBU_CLK>, 136 + <&gcc GCC_BIMC_CDSP_CLK>, 137 + <&turingcc TURING_WRAPPER_AON_CLK>, 138 + <&turingcc TURING_Q6SS_AHBS_AON_CLK>, 139 + <&turingcc TURING_Q6SS_AHBM_AON_CLK>, 140 + <&turingcc TURING_Q6SS_Q6_AXIM_CLK>; 141 + clock-names = "xo", 142 + "sway", 143 + "tbu", 144 + "bimc", 145 + "ahb_aon", 146 + "q6ss_slave", 147 + "q6ss_master", 148 + "q6_axim"; 149 + 150 + power-domains = <&rpmhpd SDM845_CX>; 151 + 152 + resets = <&gcc GCC_CDSP_RESTART>; 153 + reset-names = "restart"; 154 + 155 + qcom,halt-regs = <&tcsr 0x19004>; 156 + 157 + memory-region = <&cdsp_fw_mem>; 158 + 159 + qcom,smem-states = <&cdsp_smp2p_out 0>; 160 + qcom,smem-state-names = "stop"; 161 + };
+219
Documentation/devicetree/bindings/remoteproc/qcom,sc7280-wpss-pil.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/remoteproc/qcom,sc7280-wpss-pil.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Qualcomm SC7280 WPSS Peripheral Image Loader 8 + 9 + maintainers: 10 + - Bjorn Andersson <bjorn.andersson@linaro.org> 11 + 12 + description: 13 + This document defines the binding for a component that loads and boots firmware 14 + on the Qualcomm Technology Inc. WPSS. 15 + 16 + properties: 17 + compatible: 18 + enum: 19 + - qcom,sc7280-wpss-pil 20 + 21 + reg: 22 + maxItems: 1 23 + description: 24 + The base address and size of the qdsp6ss register 25 + 26 + interrupts: 27 + items: 28 + - description: Watchdog interrupt 29 + - description: Fatal interrupt 30 + - description: Ready interrupt 31 + - description: Handover interrupt 32 + - description: Stop acknowledge interrupt 33 + - description: Shutdown acknowledge interrupt 34 + 35 + interrupt-names: 36 + items: 37 + - const: wdog 38 + - const: fatal 39 + - const: ready 40 + - const: handover 41 + - const: stop-ack 42 + - const: shutdown-ack 43 + 44 + clocks: 45 + items: 46 + - description: GCC WPSS AHB BDG Master clock 47 + - description: GCC WPSS AHB clock 48 + - description: GCC WPSS RSCP clock 49 + - description: XO clock 50 + 51 + clock-names: 52 + items: 53 + - const: ahb_bdg 54 + - const: ahb 55 + - const: rscp 56 + - const: xo 57 + 58 + power-domains: 59 + items: 60 + - description: CX power domain 61 + - description: MX power domain 62 + 63 + power-domain-names: 64 + items: 65 + - const: cx 66 + - const: mx 67 + 68 + resets: 69 + items: 70 + - description: AOSS restart 71 + - description: PDC SYNC 72 + 73 + reset-names: 74 + items: 75 + - const: restart 76 + - const: pdc_sync 77 + 78 + memory-region: 79 + $ref: /schemas/types.yaml#/definitions/phandle 80 + description: Reference to the reserved-memory for the Hexagon core 81 + 82 + firmware-name: 83 + $ref: /schemas/types.yaml#/definitions/string 84 + description: 85 + The name of the firmware which should be loaded for this remote 86 + processor. 87 + 88 + qcom,halt-regs: 89 + $ref: /schemas/types.yaml#/definitions/phandle-array 90 + description: 91 + Phandle reference to a syscon representing TCSR followed by the 92 + three offsets within syscon for q6, modem and nc halt registers. 93 + 94 + qcom,qmp: 95 + $ref: /schemas/types.yaml#/definitions/phandle 96 + description: Reference to the AOSS side-channel message RAM. 97 + 98 + qcom,smem-states: 99 + $ref: /schemas/types.yaml#/definitions/phandle-array 100 + description: States used by the AP to signal the Hexagon core 101 + items: 102 + - description: Stop the modem 103 + 104 + qcom,smem-state-names: 105 + $ref: /schemas/types.yaml#/definitions/string 106 + description: The names of the state bits used for SMP2P output 107 + items: 108 + - const: stop 109 + 110 + glink-edge: 111 + type: object 112 + description: | 113 + Qualcomm G-Link subnode which represents communication edge, channels 114 + and devices related to the ADSP. 115 + 116 + properties: 117 + interrupts: 118 + items: 119 + - description: IRQ from WPSS to GLINK 120 + 121 + mboxes: 122 + items: 123 + - description: Mailbox for communication between APPS and WPSS 124 + 125 + label: 126 + description: The names of the state bits used for SMP2P output 127 + items: 128 + - const: wpss 129 + 130 + qcom,remote-pid: 131 + $ref: /schemas/types.yaml#/definitions/uint32 132 + description: ID of the shared memory used by GLINK for communication with WPSS 133 + maxItems: 1 134 + 135 + required: 136 + - interrupts 137 + - mboxes 138 + - label 139 + - qcom,remote-pid 140 + 141 + additionalProperties: false 142 + 143 + required: 144 + - compatible 145 + - reg 146 + - interrupts 147 + - interrupt-names 148 + - clocks 149 + - clock-names 150 + - power-domains 151 + - power-domain-names 152 + - resets 153 + - reset-names 154 + - qcom,halt-regs 155 + - memory-region 156 + - qcom,qmp 157 + - qcom,smem-states 158 + - qcom,smem-state-names 159 + - glink-edge 160 + 161 + additionalProperties: false 162 + 163 + examples: 164 + - | 165 + #include <dt-bindings/interrupt-controller/arm-gic.h> 166 + #include <dt-bindings/clock/qcom,gcc-sc7280.h> 167 + #include <dt-bindings/clock/qcom,rpmh.h> 168 + #include <dt-bindings/power/qcom-rpmpd.h> 169 + #include <dt-bindings/reset/qcom,sdm845-aoss.h> 170 + #include <dt-bindings/reset/qcom,sdm845-pdc.h> 171 + #include <dt-bindings/mailbox/qcom-ipcc.h> 172 + remoteproc@8a00000 { 173 + compatible = "qcom,sc7280-wpss-pil"; 174 + reg = <0x08a00000 0x10000>; 175 + 176 + interrupts-extended = <&intc GIC_SPI 587 IRQ_TYPE_EDGE_RISING>, 177 + <&wpss_smp2p_in 0 IRQ_TYPE_EDGE_RISING>, 178 + <&wpss_smp2p_in 1 IRQ_TYPE_EDGE_RISING>, 179 + <&wpss_smp2p_in 2 IRQ_TYPE_EDGE_RISING>, 180 + <&wpss_smp2p_in 3 IRQ_TYPE_EDGE_RISING>, 181 + <&wpss_smp2p_in 7 IRQ_TYPE_EDGE_RISING>; 182 + interrupt-names = "wdog", "fatal", "ready", "handover", 183 + "stop-ack", "shutdown-ack"; 184 + 185 + clocks = <&gcc GCC_WPSS_AHB_BDG_MST_CLK>, 186 + <&gcc GCC_WPSS_AHB_CLK>, 187 + <&gcc GCC_WPSS_RSCP_CLK>, 188 + <&rpmhcc RPMH_CXO_CLK>; 189 + clock-names = "ahb_bdg", "ahb", 190 + "rscp", "xo"; 191 + 192 + power-domains = <&rpmhpd SC7280_CX>, 193 + <&rpmhpd SC7280_MX>; 194 + power-domain-names = "cx", "mx"; 195 + 196 + memory-region = <&wpss_mem>; 197 + 198 + qcom,qmp = <&aoss_qmp>; 199 + 200 + qcom,smem-states = <&wpss_smp2p_out 0>; 201 + qcom,smem-state-names = "stop"; 202 + 203 + resets = <&aoss_reset AOSS_CC_WCSS_RESTART>, 204 + <&pdc_reset PDC_WPSS_SYNC_RESET>; 205 + reset-names = "restart", "pdc_sync"; 206 + 207 + qcom,halt-regs = <&tcsr_mutex 0x37000>; 208 + 209 + glink-edge { 210 + interrupts-extended = <&ipcc IPCC_CLIENT_WPSS 211 + IPCC_MPROC_SIGNAL_GLINK_QMP 212 + IRQ_TYPE_EDGE_RISING>; 213 + mboxes = <&ipcc IPCC_CLIENT_WPSS 214 + IPCC_MPROC_SIGNAL_GLINK_QMP>; 215 + 216 + label = "wpss"; 217 + qcom,remote-pid = <13>; 218 + }; 219 + };
+160
Documentation/devicetree/bindings/remoteproc/qcom,sdm845-adsp-pil.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/remoteproc/qcom,sdm845-adsp-pil.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Qualcomm SDM845 ADSP Peripheral Image Loader 8 + 9 + maintainers: 10 + - Bjorn Andersson <bjorn.andersson@linaro.org> 11 + 12 + description: 13 + This document defines the binding for a component that loads and boots firmware 14 + on the Qualcomm Technology Inc. ADSP. 15 + 16 + properties: 17 + compatible: 18 + enum: 19 + - qcom,sdm845-adsp-pil 20 + 21 + reg: 22 + maxItems: 1 23 + description: 24 + The base address and size of the qdsp6ss register 25 + 26 + interrupts: 27 + items: 28 + - description: Watchdog interrupt 29 + - description: Fatal interrupt 30 + - description: Ready interrupt 31 + - description: Handover interrupt 32 + - description: Stop acknowledge interrupt 33 + 34 + interrupt-names: 35 + items: 36 + - const: wdog 37 + - const: fatal 38 + - const: ready 39 + - const: handover 40 + - const: stop-ack 41 + 42 + clocks: 43 + items: 44 + - description: XO clock 45 + - description: SWAY clock 46 + - description: LPASS AHBS AON clock 47 + - description: LPASS AHBM AON clock 48 + - description: QDSP XO clock 49 + - description: Q6SP6SS SLEEP clock 50 + - description: Q6SP6SS CORE clock 51 + 52 + clock-names: 53 + items: 54 + - const: xo 55 + - const: sway_cbcr 56 + - const: lpass_ahbs_aon_cbcr 57 + - const: lpass_ahbm_aon_cbcr 58 + - const: qdsp6ss_xo 59 + - const: qdsp6ss_sleep 60 + - const: qdsp6ss_core 61 + 62 + power-domains: 63 + items: 64 + - description: CX power domain 65 + 66 + resets: 67 + items: 68 + - description: PDC AUDIO SYNC RESET 69 + - description: CC LPASS restart 70 + 71 + reset-names: 72 + items: 73 + - const: pdc_sync 74 + - const: cc_lpass 75 + 76 + memory-region: 77 + maxItems: 1 78 + description: Reference to the reserved-memory for the Hexagon core 79 + 80 + qcom,halt-regs: 81 + $ref: /schemas/types.yaml#/definitions/phandle-array 82 + description: 83 + Phandle reference to a syscon representing TCSR followed by the 84 + three offsets within syscon for q6, modem and nc halt registers. 85 + 86 + qcom,smem-states: 87 + $ref: /schemas/types.yaml#/definitions/phandle-array 88 + description: States used by the AP to signal the Hexagon core 89 + items: 90 + - description: Stop the modem 91 + 92 + qcom,smem-state-names: 93 + $ref: /schemas/types.yaml#/definitions/string 94 + description: The names of the state bits used for SMP2P output 95 + items: 96 + - const: stop 97 + 98 + required: 99 + - compatible 100 + - reg 101 + - interrupts 102 + - interrupt-names 103 + - clocks 104 + - clock-names 105 + - power-domains 106 + - resets 107 + - reset-names 108 + - qcom,halt-regs 109 + - memory-region 110 + - qcom,smem-states 111 + - qcom,smem-state-names 112 + 113 + additionalProperties: false 114 + 115 + examples: 116 + - | 117 + #include <dt-bindings/interrupt-controller/arm-gic.h> 118 + #include <dt-bindings/clock/qcom,rpmh.h> 119 + #include <dt-bindings/clock/qcom,gcc-sdm845.h> 120 + #include <dt-bindings/clock/qcom,lpass-sdm845.h> 121 + #include <dt-bindings/power/qcom-rpmpd.h> 122 + #include <dt-bindings/reset/qcom,sdm845-pdc.h> 123 + #include <dt-bindings/reset/qcom,sdm845-aoss.h> 124 + remoteproc@17300000 { 125 + compatible = "qcom,sdm845-adsp-pil"; 126 + reg = <0x17300000 0x40c>; 127 + 128 + interrupts-extended = <&intc GIC_SPI 162 IRQ_TYPE_EDGE_RISING>, 129 + <&adsp_smp2p_in 0 IRQ_TYPE_EDGE_RISING>, 130 + <&adsp_smp2p_in 1 IRQ_TYPE_EDGE_RISING>, 131 + <&adsp_smp2p_in 2 IRQ_TYPE_EDGE_RISING>, 132 + <&adsp_smp2p_in 3 IRQ_TYPE_EDGE_RISING>; 133 + interrupt-names = "wdog", "fatal", "ready", 134 + "handover", "stop-ack"; 135 + 136 + clocks = <&rpmhcc RPMH_CXO_CLK>, 137 + <&gcc GCC_LPASS_SWAY_CLK>, 138 + <&lpasscc LPASS_Q6SS_AHBS_AON_CLK>, 139 + <&lpasscc LPASS_Q6SS_AHBM_AON_CLK>, 140 + <&lpasscc LPASS_QDSP6SS_XO_CLK>, 141 + <&lpasscc LPASS_QDSP6SS_SLEEP_CLK>, 142 + <&lpasscc LPASS_QDSP6SS_CORE_CLK>; 143 + clock-names = "xo", "sway_cbcr", 144 + "lpass_ahbs_aon_cbcr", 145 + "lpass_ahbm_aon_cbcr", "qdsp6ss_xo", 146 + "qdsp6ss_sleep", "qdsp6ss_core"; 147 + 148 + power-domains = <&rpmhpd SDM845_CX>; 149 + 150 + resets = <&pdc_reset PDC_AUDIO_SYNC_RESET>, 151 + <&aoss_reset AOSS_CC_LPASS_RESTART>; 152 + reset-names = "pdc_sync", "cc_lpass"; 153 + 154 + qcom,halt-regs = <&tcsr_mutex_regs 0x22000>; 155 + 156 + memory-region = <&pil_adsp_mem>; 157 + 158 + qcom,smem-states = <&adsp_smp2p_out 0>; 159 + qcom,smem-state-names = "stop"; 160 + };
+2 -1
Documentation/staging/remoteproc.rst
··· 49 49 50 50 :: 51 51 52 - void rproc_shutdown(struct rproc *rproc) 52 + int rproc_shutdown(struct rproc *rproc) 53 53 54 54 Power off a remote processor (previously booted with rproc_boot()). 55 55 In case @rproc is still being used by an additional user(s), then 56 56 this function will just decrement the power refcount and exit, 57 57 without really powering off the device. 58 58 59 + Returns 0 on success, and an appropriate error value otherwise. 59 60 Every call to rproc_boot() must (eventually) be accompanied by a call 60 61 to rproc_shutdown(). Calling rproc_shutdown() redundantly is a bug. 61 62
+3
drivers/remoteproc/mtk_common.h
··· 32 32 #define MT8183_SCP_CACHESIZE_8KB BIT(8) 33 33 #define MT8183_SCP_CACHE_CON_WAYEN BIT(10) 34 34 35 + #define MT8186_SCP_L1_SRAM_PD_P1 0x40B0 36 + #define MT8186_SCP_L1_SRAM_PD_p2 0x40B4 37 + 35 38 #define MT8192_L2TCM_SRAM_PD_0 0x10C0 36 39 #define MT8192_L2TCM_SRAM_PD_1 0x10C4 37 40 #define MT8192_L2TCM_SRAM_PD_2 0x10C8
+57 -35
drivers/remoteproc/mtk_scp.c
··· 383 383 writel(GENMASK(i, 0), addr); 384 384 } 385 385 386 + static int mt8186_scp_before_load(struct mtk_scp *scp) 387 + { 388 + /* Clear SCP to host interrupt */ 389 + writel(MT8183_SCP_IPC_INT_BIT, scp->reg_base + MT8183_SCP_TO_HOST); 390 + 391 + /* Reset clocks before loading FW */ 392 + writel(0x0, scp->reg_base + MT8183_SCP_CLK_SW_SEL); 393 + writel(0x0, scp->reg_base + MT8183_SCP_CLK_DIV_SEL); 394 + 395 + /* Turn on the power of SCP's SRAM before using it. Enable 1 block per time*/ 396 + mt8192_power_on_sram(scp->reg_base + MT8183_SCP_SRAM_PDN); 397 + 398 + /* Initialize TCM before loading FW. */ 399 + writel(0x0, scp->reg_base + MT8183_SCP_L1_SRAM_PD); 400 + writel(0x0, scp->reg_base + MT8183_SCP_TCM_TAIL_SRAM_PD); 401 + writel(0x0, scp->reg_base + MT8186_SCP_L1_SRAM_PD_P1); 402 + writel(0x0, scp->reg_base + MT8186_SCP_L1_SRAM_PD_p2); 403 + 404 + return 0; 405 + } 406 + 386 407 static int mt8192_scp_before_load(struct mtk_scp *scp) 387 408 { 388 409 /* clear SPM interrupt, SCP2SPM_IPC_CLR */ ··· 777 756 char *fw_name = "scp.img"; 778 757 int ret, i; 779 758 780 - rproc = rproc_alloc(dev, 781 - np->name, 782 - &scp_ops, 783 - fw_name, 784 - sizeof(*scp)); 785 - if (!rproc) { 786 - dev_err(dev, "unable to allocate remoteproc\n"); 787 - return -ENOMEM; 788 - } 759 + rproc = devm_rproc_alloc(dev, np->name, &scp_ops, fw_name, sizeof(*scp)); 760 + if (!rproc) 761 + return dev_err_probe(dev, -ENOMEM, "unable to allocate remoteproc\n"); 789 762 790 763 scp = (struct mtk_scp *)rproc->priv; 791 764 scp->rproc = rproc; ··· 789 774 790 775 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sram"); 791 776 scp->sram_base = devm_ioremap_resource(dev, res); 792 - if (IS_ERR((__force void *)scp->sram_base)) { 793 - dev_err(dev, "Failed to parse and map sram memory\n"); 794 - ret = PTR_ERR((__force void *)scp->sram_base); 795 - goto free_rproc; 796 - } 777 + if (IS_ERR(scp->sram_base)) 778 + return dev_err_probe(dev, PTR_ERR(scp->sram_base), 779 + "Failed to parse and map sram memory\n"); 780 + 797 781 scp->sram_size = resource_size(res); 798 782 scp->sram_phys = res->start; 799 783 800 784 /* l1tcm is an optional memory region */ 801 785 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "l1tcm"); 802 786 scp->l1tcm_base = devm_ioremap_resource(dev, res); 803 - if (IS_ERR((__force void *)scp->l1tcm_base)) { 804 - ret = PTR_ERR((__force void *)scp->l1tcm_base); 787 + if (IS_ERR(scp->l1tcm_base)) { 788 + ret = PTR_ERR(scp->l1tcm_base); 805 789 if (ret != -EINVAL) { 806 - dev_err(dev, "Failed to map l1tcm memory\n"); 807 - goto free_rproc; 790 + return dev_err_probe(dev, ret, "Failed to map l1tcm memory\n"); 808 791 } 809 792 } else { 810 793 scp->l1tcm_size = resource_size(res); 811 794 scp->l1tcm_phys = res->start; 812 795 } 813 796 814 - mutex_init(&scp->send_lock); 815 - for (i = 0; i < SCP_IPI_MAX; i++) 816 - mutex_init(&scp->ipi_desc[i].lock); 817 - 818 797 scp->reg_base = devm_platform_ioremap_resource_byname(pdev, "cfg"); 819 - if (IS_ERR((__force void *)scp->reg_base)) { 820 - dev_err(dev, "Failed to parse and map cfg memory\n"); 821 - ret = PTR_ERR((__force void *)scp->reg_base); 822 - goto destroy_mutex; 823 - } 824 - 825 - ret = scp_map_memory_region(scp); 826 - if (ret) 827 - goto destroy_mutex; 798 + if (IS_ERR(scp->reg_base)) 799 + return dev_err_probe(dev, PTR_ERR(scp->reg_base), 800 + "Failed to parse and map cfg memory\n"); 828 801 829 802 ret = scp->data->scp_clk_get(scp); 830 803 if (ret) 831 - goto release_dev_mem; 804 + return ret; 805 + 806 + ret = scp_map_memory_region(scp); 807 + if (ret) 808 + return ret; 809 + 810 + mutex_init(&scp->send_lock); 811 + for (i = 0; i < SCP_IPI_MAX; i++) 812 + mutex_init(&scp->ipi_desc[i].lock); 832 813 833 814 /* register SCP initialization IPI */ 834 815 ret = scp_ipi_register(scp, SCP_IPI_INIT, scp_init_ipi_handler, scp); ··· 858 847 scp_ipi_unregister(scp, SCP_IPI_INIT); 859 848 release_dev_mem: 860 849 scp_unmap_memory_region(scp); 861 - destroy_mutex: 862 850 for (i = 0; i < SCP_IPI_MAX; i++) 863 851 mutex_destroy(&scp->ipi_desc[i].lock); 864 852 mutex_destroy(&scp->send_lock); 865 - free_rproc: 866 - rproc_free(rproc); 867 853 868 854 return ret; 869 855 } ··· 885 877 static const struct mtk_scp_of_data mt8183_of_data = { 886 878 .scp_clk_get = mt8183_scp_clk_get, 887 879 .scp_before_load = mt8183_scp_before_load, 880 + .scp_irq_handler = mt8183_scp_irq_handler, 881 + .scp_reset_assert = mt8183_scp_reset_assert, 882 + .scp_reset_deassert = mt8183_scp_reset_deassert, 883 + .scp_stop = mt8183_scp_stop, 884 + .scp_da_to_va = mt8183_scp_da_to_va, 885 + .host_to_scp_reg = MT8183_HOST_TO_SCP, 886 + .host_to_scp_int_bit = MT8183_HOST_IPC_INT_BIT, 887 + .ipi_buf_offset = 0x7bdb0, 888 + }; 889 + 890 + static const struct mtk_scp_of_data mt8186_of_data = { 891 + .scp_clk_get = mt8195_scp_clk_get, 892 + .scp_before_load = mt8186_scp_before_load, 888 893 .scp_irq_handler = mt8183_scp_irq_handler, 889 894 .scp_reset_assert = mt8183_scp_reset_assert, 890 895 .scp_reset_deassert = mt8183_scp_reset_deassert, ··· 934 913 935 914 static const struct of_device_id mtk_scp_of_match[] = { 936 915 { .compatible = "mediatek,mt8183-scp", .data = &mt8183_of_data }, 916 + { .compatible = "mediatek,mt8186-scp", .data = &mt8186_of_data }, 937 917 { .compatible = "mediatek,mt8192-scp", .data = &mt8192_of_data }, 938 918 { .compatible = "mediatek,mt8195-scp", .data = &mt8195_of_data }, 939 919 {},
+21 -2
drivers/remoteproc/qcom_q6v5.c
··· 8 8 */ 9 9 #include <linux/kernel.h> 10 10 #include <linux/platform_device.h> 11 + #include <linux/interconnect.h> 11 12 #include <linux/interrupt.h> 12 13 #include <linux/module.h> 13 14 #include <linux/soc/qcom/qcom_aoss.h> ··· 52 51 { 53 52 int ret; 54 53 55 - ret = q6v5_load_state_toggle(q6v5, true); 56 - if (ret) 54 + ret = icc_set_bw(q6v5->path, 0, UINT_MAX); 55 + if (ret < 0) { 56 + dev_err(q6v5->dev, "failed to set bandwidth request\n"); 57 57 return ret; 58 + } 59 + 60 + ret = q6v5_load_state_toggle(q6v5, true); 61 + if (ret) { 62 + icc_set_bw(q6v5->path, 0, 0); 63 + return ret; 64 + } 58 65 59 66 reinit_completion(&q6v5->start_done); 60 67 reinit_completion(&q6v5->stop_done); ··· 86 77 { 87 78 disable_irq(q6v5->handover_irq); 88 79 q6v5_load_state_toggle(q6v5, false); 80 + 81 + /* Disable interconnect vote, in case handover never happened */ 82 + icc_set_bw(q6v5->path, 0, 0); 89 83 90 84 return !q6v5->handover_issued; 91 85 } ··· 171 159 172 160 if (q6v5->handover) 173 161 q6v5->handover(q6v5); 162 + 163 + icc_set_bw(q6v5->path, 0, 0); 174 164 175 165 q6v5->handover_issued = true; 176 166 ··· 345 331 qmp_put(q6v5->qmp); 346 332 return load_state ? -ENOMEM : -EINVAL; 347 333 } 334 + 335 + q6v5->path = devm_of_icc_get(&pdev->dev, NULL); 336 + if (IS_ERR(q6v5->path)) 337 + return dev_err_probe(&pdev->dev, PTR_ERR(q6v5->path), 338 + "failed to acquire interconnect path\n"); 348 339 349 340 return 0; 350 341 }
+3
drivers/remoteproc/qcom_q6v5.h
··· 7 7 #include <linux/completion.h> 8 8 #include <linux/soc/qcom/qcom_aoss.h> 9 9 10 + struct icc_path; 10 11 struct rproc; 11 12 struct qcom_smem_state; 12 13 struct qcom_sysmon; ··· 18 17 19 18 struct qcom_smem_state *state; 20 19 struct qmp *qmp; 20 + 21 + struct icc_path *path; 21 22 22 23 unsigned stop_bit; 23 24
+212 -16
drivers/remoteproc/qcom_q6v5_adsp.c
··· 32 32 33 33 /* time out value */ 34 34 #define ACK_TIMEOUT 1000 35 + #define ACK_TIMEOUT_US 1000000 35 36 #define BOOT_FSM_TIMEOUT 10000 36 37 /* mask values */ 37 38 #define EVB_MASK GENMASK(27, 4) ··· 52 51 #define QDSP6SS_CORE_CBCR 0x20 53 52 #define QDSP6SS_SLEEP_CBCR 0x3c 54 53 54 + #define QCOM_Q6V5_RPROC_PROXY_PD_MAX 3 55 + 55 56 struct adsp_pil_data { 56 57 int crash_reason_smem; 57 58 const char *firmware_name; ··· 61 58 const char *ssr_name; 62 59 const char *sysmon_name; 63 60 int ssctl_id; 61 + bool is_wpss; 62 + bool auto_boot; 64 63 65 64 const char **clk_ids; 66 65 int num_clks; 66 + const char **proxy_pd_names; 67 + const char *load_state; 67 68 }; 68 69 69 70 struct qcom_adsp { ··· 100 93 void *mem_region; 101 94 size_t mem_size; 102 95 96 + struct device *proxy_pds[QCOM_Q6V5_RPROC_PROXY_PD_MAX]; 97 + size_t proxy_pd_count; 98 + 103 99 struct qcom_rproc_glink glink_subdev; 104 100 struct qcom_rproc_ssr ssr_subdev; 105 101 struct qcom_sysmon *sysmon; 102 + 103 + int (*shutdown)(struct qcom_adsp *adsp); 106 104 }; 105 + 106 + static int qcom_rproc_pds_attach(struct device *dev, struct qcom_adsp *adsp, 107 + const char **pd_names) 108 + { 109 + struct device **devs = adsp->proxy_pds; 110 + size_t num_pds = 0; 111 + int ret; 112 + int i; 113 + 114 + if (!pd_names) 115 + return 0; 116 + 117 + /* Handle single power domain */ 118 + if (dev->pm_domain) { 119 + devs[0] = dev; 120 + pm_runtime_enable(dev); 121 + return 1; 122 + } 123 + 124 + while (pd_names[num_pds]) 125 + num_pds++; 126 + 127 + if (num_pds > ARRAY_SIZE(adsp->proxy_pds)) 128 + return -E2BIG; 129 + 130 + for (i = 0; i < num_pds; i++) { 131 + devs[i] = dev_pm_domain_attach_by_name(dev, pd_names[i]); 132 + if (IS_ERR_OR_NULL(devs[i])) { 133 + ret = PTR_ERR(devs[i]) ? : -ENODATA; 134 + goto unroll_attach; 135 + } 136 + } 137 + 138 + return num_pds; 139 + 140 + unroll_attach: 141 + for (i--; i >= 0; i--) 142 + dev_pm_domain_detach(devs[i], false); 143 + 144 + return ret; 145 + } 146 + 147 + static void qcom_rproc_pds_detach(struct qcom_adsp *adsp, struct device **pds, 148 + size_t pd_count) 149 + { 150 + struct device *dev = adsp->dev; 151 + int i; 152 + 153 + /* Handle single power domain */ 154 + if (dev->pm_domain && pd_count) { 155 + pm_runtime_disable(dev); 156 + return; 157 + } 158 + 159 + for (i = 0; i < pd_count; i++) 160 + dev_pm_domain_detach(pds[i], false); 161 + } 162 + 163 + static int qcom_rproc_pds_enable(struct qcom_adsp *adsp, struct device **pds, 164 + size_t pd_count) 165 + { 166 + int ret; 167 + int i; 168 + 169 + for (i = 0; i < pd_count; i++) { 170 + dev_pm_genpd_set_performance_state(pds[i], INT_MAX); 171 + ret = pm_runtime_get_sync(pds[i]); 172 + if (ret < 0) { 173 + pm_runtime_put_noidle(pds[i]); 174 + dev_pm_genpd_set_performance_state(pds[i], 0); 175 + goto unroll_pd_votes; 176 + } 177 + } 178 + 179 + return 0; 180 + 181 + unroll_pd_votes: 182 + for (i--; i >= 0; i--) { 183 + dev_pm_genpd_set_performance_state(pds[i], 0); 184 + pm_runtime_put(pds[i]); 185 + } 186 + 187 + return ret; 188 + } 189 + 190 + static void qcom_rproc_pds_disable(struct qcom_adsp *adsp, struct device **pds, 191 + size_t pd_count) 192 + { 193 + int i; 194 + 195 + for (i = 0; i < pd_count; i++) { 196 + dev_pm_genpd_set_performance_state(pds[i], 0); 197 + pm_runtime_put(pds[i]); 198 + } 199 + } 200 + 201 + static int qcom_wpss_shutdown(struct qcom_adsp *adsp) 202 + { 203 + unsigned int val; 204 + 205 + regmap_write(adsp->halt_map, adsp->halt_lpass + LPASS_HALTREQ_REG, 1); 206 + 207 + /* Wait for halt ACK from QDSP6 */ 208 + regmap_read_poll_timeout(adsp->halt_map, 209 + adsp->halt_lpass + LPASS_HALTACK_REG, val, 210 + val, 1000, ACK_TIMEOUT_US); 211 + 212 + /* Assert the WPSS PDC Reset */ 213 + reset_control_assert(adsp->pdc_sync_reset); 214 + 215 + /* Place the WPSS processor into reset */ 216 + reset_control_assert(adsp->restart); 217 + 218 + /* wait after asserting subsystem restart from AOSS */ 219 + usleep_range(200, 205); 220 + 221 + /* Remove the WPSS reset */ 222 + reset_control_deassert(adsp->restart); 223 + 224 + /* De-assert the WPSS PDC Reset */ 225 + reset_control_deassert(adsp->pdc_sync_reset); 226 + 227 + usleep_range(100, 105); 228 + 229 + clk_bulk_disable_unprepare(adsp->num_clks, adsp->clks); 230 + 231 + regmap_write(adsp->halt_map, adsp->halt_lpass + LPASS_HALTREQ_REG, 0); 232 + 233 + /* Wait for halt ACK from QDSP6 */ 234 + regmap_read_poll_timeout(adsp->halt_map, 235 + adsp->halt_lpass + LPASS_HALTACK_REG, val, 236 + !val, 1000, ACK_TIMEOUT_US); 237 + 238 + return 0; 239 + } 107 240 108 241 static int qcom_adsp_shutdown(struct qcom_adsp *adsp) 109 242 { ··· 340 193 if (ret) 341 194 goto disable_irqs; 342 195 343 - dev_pm_genpd_set_performance_state(adsp->dev, INT_MAX); 344 - ret = pm_runtime_get_sync(adsp->dev); 345 - if (ret) { 346 - pm_runtime_put_noidle(adsp->dev); 196 + ret = qcom_rproc_pds_enable(adsp, adsp->proxy_pds, 197 + adsp->proxy_pd_count); 198 + if (ret < 0) 347 199 goto disable_xo_clk; 348 - } 349 200 350 201 ret = clk_bulk_prepare_enable(adsp->num_clks, adsp->clks); 351 202 if (ret) { ··· 388 243 disable_adsp_clks: 389 244 clk_bulk_disable_unprepare(adsp->num_clks, adsp->clks); 390 245 disable_power_domain: 391 - dev_pm_genpd_set_performance_state(adsp->dev, 0); 392 - pm_runtime_put(adsp->dev); 246 + qcom_rproc_pds_disable(adsp, adsp->proxy_pds, adsp->proxy_pd_count); 393 247 disable_xo_clk: 394 248 clk_disable_unprepare(adsp->xo); 395 249 disable_irqs: ··· 402 258 struct qcom_adsp *adsp = container_of(q6v5, struct qcom_adsp, q6v5); 403 259 404 260 clk_disable_unprepare(adsp->xo); 405 - dev_pm_genpd_set_performance_state(adsp->dev, 0); 406 - pm_runtime_put(adsp->dev); 261 + qcom_rproc_pds_disable(adsp, adsp->proxy_pds, adsp->proxy_pd_count); 407 262 } 408 263 409 264 static int adsp_stop(struct rproc *rproc) ··· 415 272 if (ret == -ETIMEDOUT) 416 273 dev_err(adsp->dev, "timed out on wait\n"); 417 274 418 - ret = qcom_adsp_shutdown(adsp); 275 + ret = adsp->shutdown(adsp); 419 276 if (ret) 420 277 dev_err(adsp->dev, "failed to shutdown: %d\n", ret); 421 278 ··· 551 408 } 552 409 553 410 ret = of_address_to_resource(node, 0, &r); 411 + of_node_put(node); 554 412 if (ret) 555 413 return ret; 556 414 ··· 571 427 static int adsp_probe(struct platform_device *pdev) 572 428 { 573 429 const struct adsp_pil_data *desc; 430 + const char *firmware_name; 574 431 struct qcom_adsp *adsp; 575 432 struct rproc *rproc; 576 433 int ret; ··· 580 435 if (!desc) 581 436 return -EINVAL; 582 437 438 + firmware_name = desc->firmware_name; 439 + ret = of_property_read_string(pdev->dev.of_node, "firmware-name", 440 + &firmware_name); 441 + if (ret < 0 && ret != -EINVAL) { 442 + dev_err(&pdev->dev, "unable to read firmware-name\n"); 443 + return ret; 444 + } 445 + 583 446 rproc = rproc_alloc(&pdev->dev, pdev->name, &adsp_ops, 584 - desc->firmware_name, sizeof(*adsp)); 447 + firmware_name, sizeof(*adsp)); 585 448 if (!rproc) { 586 449 dev_err(&pdev->dev, "unable to allocate remoteproc\n"); 587 450 return -ENOMEM; 588 451 } 452 + 453 + rproc->auto_boot = desc->auto_boot; 589 454 rproc_coredump_set_elf_info(rproc, ELFCLASS32, EM_NONE); 590 455 591 456 adsp = (struct qcom_adsp *)rproc->priv; ··· 603 448 adsp->rproc = rproc; 604 449 adsp->info_name = desc->sysmon_name; 605 450 platform_set_drvdata(pdev, adsp); 451 + 452 + if (desc->is_wpss) 453 + adsp->shutdown = qcom_wpss_shutdown; 454 + else 455 + adsp->shutdown = qcom_adsp_shutdown; 606 456 607 457 ret = adsp_alloc_memory_region(adsp); 608 458 if (ret) ··· 617 457 if (ret) 618 458 goto free_rproc; 619 459 620 - pm_runtime_enable(adsp->dev); 460 + ret = qcom_rproc_pds_attach(adsp->dev, adsp, 461 + desc->proxy_pd_names); 462 + if (ret < 0) { 463 + dev_err(&pdev->dev, "Failed to attach proxy power domains\n"); 464 + goto free_rproc; 465 + } 466 + adsp->proxy_pd_count = ret; 621 467 622 468 ret = adsp_init_reset(adsp); 623 469 if (ret) ··· 633 467 if (ret) 634 468 goto disable_pm; 635 469 636 - ret = qcom_q6v5_init(&adsp->q6v5, pdev, rproc, desc->crash_reason_smem, NULL, 637 - qcom_adsp_pil_handover); 470 + ret = qcom_q6v5_init(&adsp->q6v5, pdev, rproc, desc->crash_reason_smem, 471 + desc->load_state, qcom_adsp_pil_handover); 638 472 if (ret) 639 473 goto disable_pm; 640 474 ··· 655 489 return 0; 656 490 657 491 disable_pm: 658 - pm_runtime_disable(adsp->dev); 492 + qcom_rproc_pds_detach(adsp, adsp->proxy_pds, adsp->proxy_pd_count); 493 + 659 494 free_rproc: 660 495 rproc_free(rproc); 661 496 ··· 673 506 qcom_remove_glink_subdev(adsp->rproc, &adsp->glink_subdev); 674 507 qcom_remove_sysmon_subdev(adsp->sysmon); 675 508 qcom_remove_ssr_subdev(adsp->rproc, &adsp->ssr_subdev); 676 - pm_runtime_disable(adsp->dev); 509 + qcom_rproc_pds_detach(adsp, adsp->proxy_pds, adsp->proxy_pd_count); 677 510 rproc_free(adsp->rproc); 678 511 679 512 return 0; ··· 685 518 .ssr_name = "lpass", 686 519 .sysmon_name = "adsp", 687 520 .ssctl_id = 0x14, 521 + .is_wpss = false, 522 + .auto_boot = true, 688 523 .clk_ids = (const char*[]) { 689 524 "sway_cbcr", "lpass_ahbs_aon_cbcr", "lpass_ahbm_aon_cbcr", 690 525 "qdsp6ss_xo", "qdsp6ss_sleep", "qdsp6ss_core", NULL 691 526 }, 692 527 .num_clks = 7, 528 + .proxy_pd_names = (const char*[]) { 529 + "cx", NULL 530 + }, 693 531 }; 694 532 695 533 static const struct adsp_pil_data cdsp_resource_init = { ··· 703 531 .ssr_name = "cdsp", 704 532 .sysmon_name = "cdsp", 705 533 .ssctl_id = 0x17, 534 + .is_wpss = false, 535 + .auto_boot = true, 706 536 .clk_ids = (const char*[]) { 707 537 "sway", "tbu", "bimc", "ahb_aon", "q6ss_slave", "q6ss_master", 708 538 "q6_axim", NULL 709 539 }, 710 540 .num_clks = 7, 541 + .proxy_pd_names = (const char*[]) { 542 + "cx", NULL 543 + }, 544 + }; 545 + 546 + static const struct adsp_pil_data wpss_resource_init = { 547 + .crash_reason_smem = 626, 548 + .firmware_name = "wpss.mdt", 549 + .ssr_name = "wpss", 550 + .sysmon_name = "wpss", 551 + .ssctl_id = 0x19, 552 + .is_wpss = true, 553 + .auto_boot = false, 554 + .load_state = "wpss", 555 + .clk_ids = (const char*[]) { 556 + "ahb_bdg", "ahb", "rscp", NULL 557 + }, 558 + .num_clks = 3, 559 + .proxy_pd_names = (const char*[]) { 560 + "cx", "mx", NULL 561 + }, 711 562 }; 712 563 713 564 static const struct of_device_id adsp_of_match[] = { 714 565 { .compatible = "qcom,qcs404-cdsp-pil", .data = &cdsp_resource_init }, 566 + { .compatible = "qcom,sc7280-wpss-pil", .data = &wpss_resource_init }, 715 567 { .compatible = "qcom,sdm845-adsp-pil", .data = &adsp_resource_init }, 716 568 { }, 717 569 };
+15 -4
drivers/remoteproc/qcom_q6v5_mss.c
··· 218 218 struct qcom_rproc_subdev smd_subdev; 219 219 struct qcom_rproc_ssr ssr_subdev; 220 220 struct qcom_sysmon *sysmon; 221 + struct platform_device *bam_dmux; 221 222 bool need_mem_protection; 222 223 bool has_alt_reset; 223 224 bool has_mba_logs; ··· 1808 1807 * reserved memory regions from device's memory-region property. 1809 1808 */ 1810 1809 child = of_get_child_by_name(qproc->dev->of_node, "mba"); 1811 - if (!child) 1810 + if (!child) { 1812 1811 node = of_parse_phandle(qproc->dev->of_node, 1813 1812 "memory-region", 0); 1814 - else 1813 + } else { 1815 1814 node = of_parse_phandle(child, "memory-region", 0); 1815 + of_node_put(child); 1816 + } 1816 1817 1817 1818 ret = of_address_to_resource(node, 0, &r); 1819 + of_node_put(node); 1818 1820 if (ret) { 1819 1821 dev_err(qproc->dev, "unable to resolve mba region\n"); 1820 1822 return ret; 1821 1823 } 1822 - of_node_put(node); 1823 1824 1824 1825 qproc->mba_phys = r.start; 1825 1826 qproc->mba_size = resource_size(&r); ··· 1832 1829 } else { 1833 1830 child = of_get_child_by_name(qproc->dev->of_node, "mpss"); 1834 1831 node = of_parse_phandle(child, "memory-region", 0); 1832 + of_node_put(child); 1835 1833 } 1836 1834 1837 1835 ret = of_address_to_resource(node, 0, &r); 1836 + of_node_put(node); 1838 1837 if (ret) { 1839 1838 dev_err(qproc->dev, "unable to resolve mpss region\n"); 1840 1839 return ret; 1841 1840 } 1842 - of_node_put(node); 1843 1841 1844 1842 qproc->mpss_phys = qproc->mpss_reloc = r.start; 1845 1843 qproc->mpss_size = resource_size(&r); ··· 1851 1847 static int q6v5_probe(struct platform_device *pdev) 1852 1848 { 1853 1849 const struct rproc_hexagon_res *desc; 1850 + struct device_node *node; 1854 1851 struct q6v5 *qproc; 1855 1852 struct rproc *rproc; 1856 1853 const char *mba_image; ··· 1995 1990 if (ret) 1996 1991 goto remove_sysmon_subdev; 1997 1992 1993 + node = of_get_compatible_child(pdev->dev.of_node, "qcom,bam-dmux"); 1994 + qproc->bam_dmux = of_platform_device_create(node, NULL, &pdev->dev); 1995 + of_node_put(node); 1996 + 1998 1997 return 0; 1999 1998 2000 1999 remove_sysmon_subdev: ··· 2020 2011 struct q6v5 *qproc = platform_get_drvdata(pdev); 2021 2012 struct rproc *rproc = qproc->rproc; 2022 2013 2014 + if (qproc->bam_dmux) 2015 + of_platform_device_destroy(&qproc->bam_dmux->dev, NULL); 2023 2016 rproc_del(rproc); 2024 2017 2025 2018 qcom_q6v5_deinit(&qproc->q6v5);
+1
drivers/remoteproc/qcom_wcnss.c
··· 500 500 } 501 501 502 502 ret = of_address_to_resource(node, 0, &r); 503 + of_node_put(node); 503 504 if (ret) 504 505 return ret; 505 506
+1 -1
drivers/remoteproc/remoteproc_cdev.c
··· 42 42 rproc->state != RPROC_ATTACHED) 43 43 return -EINVAL; 44 44 45 - rproc_shutdown(rproc); 45 + ret = rproc_shutdown(rproc); 46 46 } else if (!strncmp(cmd, "detach", len)) { 47 47 if (rproc->state != RPROC_ATTACHED) 48 48 return -EINVAL;
+6 -3
drivers/remoteproc/remoteproc_core.c
··· 2061 2061 * which means that the @rproc handle stays valid even after rproc_shutdown() 2062 2062 * returns, and users can still use it with a subsequent rproc_boot(), if 2063 2063 * needed. 2064 + * 2065 + * Return: 0 on success, and an appropriate error value otherwise 2064 2066 */ 2065 - void rproc_shutdown(struct rproc *rproc) 2067 + int rproc_shutdown(struct rproc *rproc) 2066 2068 { 2067 2069 struct device *dev = &rproc->dev; 2068 - int ret; 2070 + int ret = 0; 2069 2071 2070 2072 ret = mutex_lock_interruptible(&rproc->lock); 2071 2073 if (ret) { 2072 2074 dev_err(dev, "can't lock rproc %s: %d\n", rproc->name, ret); 2073 - return; 2075 + return ret; 2074 2076 } 2075 2077 2076 2078 /* if the remote proc is still needed, bail out */ ··· 2099 2097 rproc->table_ptr = NULL; 2100 2098 out: 2101 2099 mutex_unlock(&rproc->lock); 2100 + return ret; 2102 2101 } 2103 2102 EXPORT_SYMBOL(rproc_shutdown); 2104 2103
+1 -1
drivers/remoteproc/remoteproc_debugfs.c
··· 76 76 int ret, err = 0; 77 77 char buf[20]; 78 78 79 - if (count > sizeof(buf)) 79 + if (count < 1 || count > sizeof(buf)) 80 80 return -EINVAL; 81 81 82 82 ret = copy_from_user(buf, user_buf, count);
-1
drivers/remoteproc/remoteproc_internal.h
··· 84 84 void rproc_free_vring(struct rproc_vring *rvring); 85 85 int rproc_alloc_vring(struct rproc_vdev *rvdev, int i); 86 86 87 - void *rproc_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem); 88 87 phys_addr_t rproc_va_to_pa(void *cpu_addr); 89 88 int rproc_trigger_recovery(struct rproc *rproc); 90 89
+19 -2
drivers/remoteproc/remoteproc_sysfs.c
··· 206 206 rproc->state != RPROC_ATTACHED) 207 207 return -EINVAL; 208 208 209 - rproc_shutdown(rproc); 209 + ret = rproc_shutdown(rproc); 210 210 } else if (sysfs_streq(buf, "detach")) { 211 211 if (rproc->state != RPROC_ATTACHED) 212 212 return -EINVAL; ··· 230 230 } 231 231 static DEVICE_ATTR_RO(name); 232 232 233 + static umode_t rproc_is_visible(struct kobject *kobj, struct attribute *attr, 234 + int n) 235 + { 236 + struct device *dev = kobj_to_dev(kobj); 237 + struct rproc *rproc = to_rproc(dev); 238 + umode_t mode = attr->mode; 239 + 240 + if (rproc->sysfs_read_only && (attr == &dev_attr_recovery.attr || 241 + attr == &dev_attr_firmware.attr || 242 + attr == &dev_attr_state.attr || 243 + attr == &dev_attr_coredump.attr)) 244 + mode = 0444; 245 + 246 + return mode; 247 + } 248 + 233 249 static struct attribute *rproc_attrs[] = { 234 250 &dev_attr_coredump.attr, 235 251 &dev_attr_recovery.attr, ··· 256 240 }; 257 241 258 242 static const struct attribute_group rproc_devgroup = { 259 - .attrs = rproc_attrs 243 + .attrs = rproc_attrs, 244 + .is_visible = rproc_is_visible, 260 245 }; 261 246 262 247 static const struct attribute_group *rproc_devgroups[] = {
+192 -72
drivers/remoteproc/ti_k3_dsp_remoteproc.c
··· 2 2 /* 3 3 * TI K3 DSP Remote Processor(s) driver 4 4 * 5 - * Copyright (C) 2018-2020 Texas Instruments Incorporated - https://www.ti.com/ 5 + * Copyright (C) 2018-2022 Texas Instruments Incorporated - https://www.ti.com/ 6 6 * Suman Anna <s-anna@ti.com> 7 7 */ 8 8 ··· 216 216 return ret; 217 217 } 218 218 219 - /* 220 - * The C66x DSP cores have a local reset that affects only the CPU, and a 221 - * generic module reset that powers on the device and allows the DSP internal 222 - * memories to be accessed while the local reset is asserted. This function is 223 - * used to release the global reset on C66x DSPs to allow loading into the DSP 224 - * internal RAMs. The .prepare() ops is invoked by remoteproc core before any 225 - * firmware loading, and is followed by the .start() ops after loading to 226 - * actually let the C66x DSP cores run. 227 - */ 228 - static int k3_dsp_rproc_prepare(struct rproc *rproc) 229 - { 230 - struct k3_dsp_rproc *kproc = rproc->priv; 231 - struct device *dev = kproc->dev; 232 - int ret; 233 - 234 - ret = kproc->ti_sci->ops.dev_ops.get_device(kproc->ti_sci, 235 - kproc->ti_sci_id); 236 - if (ret) 237 - dev_err(dev, "module-reset deassert failed, cannot enable internal RAM loading, ret = %d\n", 238 - ret); 239 - 240 - return ret; 241 - } 242 - 243 - /* 244 - * This function implements the .unprepare() ops and performs the complimentary 245 - * operations to that of the .prepare() ops. The function is used to assert the 246 - * global reset on applicable C66x cores. This completes the second portion of 247 - * powering down the C66x DSP cores. The cores themselves are only halted in the 248 - * .stop() callback through the local reset, and the .unprepare() ops is invoked 249 - * by the remoteproc core after the remoteproc is stopped to balance the global 250 - * reset. 251 - */ 252 - static int k3_dsp_rproc_unprepare(struct rproc *rproc) 253 - { 254 - struct k3_dsp_rproc *kproc = rproc->priv; 255 - struct device *dev = kproc->dev; 256 - int ret; 257 - 258 - ret = kproc->ti_sci->ops.dev_ops.put_device(kproc->ti_sci, 259 - kproc->ti_sci_id); 260 - if (ret) 261 - dev_err(dev, "module-reset assert failed, ret = %d\n", ret); 262 - 263 - return ret; 264 - } 265 - 266 - /* 267 - * Power up the DSP remote processor. 268 - * 269 - * This function will be invoked only after the firmware for this rproc 270 - * was loaded, parsed successfully, and all of its resource requirements 271 - * were met. 272 - */ 273 - static int k3_dsp_rproc_start(struct rproc *rproc) 219 + static int k3_dsp_rproc_request_mbox(struct rproc *rproc) 274 220 { 275 221 struct k3_dsp_rproc *kproc = rproc->priv; 276 222 struct mbox_client *client = &kproc->client; 277 223 struct device *dev = kproc->dev; 278 - u32 boot_addr; 279 224 int ret; 280 225 281 226 client->dev = dev; ··· 247 302 ret = mbox_send_message(kproc->mbox, (void *)RP_MBOX_ECHO_REQUEST); 248 303 if (ret < 0) { 249 304 dev_err(dev, "mbox_send_message failed: %d\n", ret); 250 - goto put_mbox; 305 + mbox_free_channel(kproc->mbox); 306 + return ret; 251 307 } 308 + 309 + return 0; 310 + } 311 + /* 312 + * The C66x DSP cores have a local reset that affects only the CPU, and a 313 + * generic module reset that powers on the device and allows the DSP internal 314 + * memories to be accessed while the local reset is asserted. This function is 315 + * used to release the global reset on C66x DSPs to allow loading into the DSP 316 + * internal RAMs. The .prepare() ops is invoked by remoteproc core before any 317 + * firmware loading, and is followed by the .start() ops after loading to 318 + * actually let the C66x DSP cores run. This callback is invoked only in 319 + * remoteproc mode. 320 + */ 321 + static int k3_dsp_rproc_prepare(struct rproc *rproc) 322 + { 323 + struct k3_dsp_rproc *kproc = rproc->priv; 324 + struct device *dev = kproc->dev; 325 + int ret; 326 + 327 + ret = kproc->ti_sci->ops.dev_ops.get_device(kproc->ti_sci, 328 + kproc->ti_sci_id); 329 + if (ret) 330 + dev_err(dev, "module-reset deassert failed, cannot enable internal RAM loading, ret = %d\n", 331 + ret); 332 + 333 + return ret; 334 + } 335 + 336 + /* 337 + * This function implements the .unprepare() ops and performs the complimentary 338 + * operations to that of the .prepare() ops. The function is used to assert the 339 + * global reset on applicable C66x cores. This completes the second portion of 340 + * powering down the C66x DSP cores. The cores themselves are only halted in the 341 + * .stop() callback through the local reset, and the .unprepare() ops is invoked 342 + * by the remoteproc core after the remoteproc is stopped to balance the global 343 + * reset. This callback is invoked only in remoteproc mode. 344 + */ 345 + static int k3_dsp_rproc_unprepare(struct rproc *rproc) 346 + { 347 + struct k3_dsp_rproc *kproc = rproc->priv; 348 + struct device *dev = kproc->dev; 349 + int ret; 350 + 351 + ret = kproc->ti_sci->ops.dev_ops.put_device(kproc->ti_sci, 352 + kproc->ti_sci_id); 353 + if (ret) 354 + dev_err(dev, "module-reset assert failed, ret = %d\n", ret); 355 + 356 + return ret; 357 + } 358 + 359 + /* 360 + * Power up the DSP remote processor. 361 + * 362 + * This function will be invoked only after the firmware for this rproc 363 + * was loaded, parsed successfully, and all of its resource requirements 364 + * were met. This callback is invoked only in remoteproc mode. 365 + */ 366 + static int k3_dsp_rproc_start(struct rproc *rproc) 367 + { 368 + struct k3_dsp_rproc *kproc = rproc->priv; 369 + struct device *dev = kproc->dev; 370 + u32 boot_addr; 371 + int ret; 372 + 373 + ret = k3_dsp_rproc_request_mbox(rproc); 374 + if (ret) 375 + return ret; 252 376 253 377 boot_addr = rproc->bootaddr; 254 378 if (boot_addr & (kproc->data->boot_align_addr - 1)) { ··· 347 333 * Stop the DSP remote processor. 348 334 * 349 335 * This function puts the DSP processor into reset, and finishes processing 350 - * of any pending messages. 336 + * of any pending messages. This callback is invoked only in remoteproc mode. 351 337 */ 352 338 static int k3_dsp_rproc_stop(struct rproc *rproc) 353 339 { ··· 358 344 k3_dsp_rproc_reset(kproc); 359 345 360 346 return 0; 347 + } 348 + 349 + /* 350 + * Attach to a running DSP remote processor (IPC-only mode) 351 + * 352 + * This rproc attach callback only needs to request the mailbox, the remote 353 + * processor is already booted, so there is no need to issue any TI-SCI 354 + * commands to boot the DSP core. This callback is invoked only in IPC-only 355 + * mode. 356 + */ 357 + static int k3_dsp_rproc_attach(struct rproc *rproc) 358 + { 359 + struct k3_dsp_rproc *kproc = rproc->priv; 360 + struct device *dev = kproc->dev; 361 + int ret; 362 + 363 + ret = k3_dsp_rproc_request_mbox(rproc); 364 + if (ret) 365 + return ret; 366 + 367 + dev_info(dev, "DSP initialized in IPC-only mode\n"); 368 + return 0; 369 + } 370 + 371 + /* 372 + * Detach from a running DSP remote processor (IPC-only mode) 373 + * 374 + * This rproc detach callback performs the opposite operation to attach callback 375 + * and only needs to release the mailbox, the DSP core is not stopped and will 376 + * be left to continue to run its booted firmware. This callback is invoked only 377 + * in IPC-only mode. 378 + */ 379 + static int k3_dsp_rproc_detach(struct rproc *rproc) 380 + { 381 + struct k3_dsp_rproc *kproc = rproc->priv; 382 + struct device *dev = kproc->dev; 383 + 384 + mbox_free_channel(kproc->mbox); 385 + dev_info(dev, "DSP deinitialized in IPC-only mode\n"); 386 + return 0; 387 + } 388 + 389 + /* 390 + * This function implements the .get_loaded_rsc_table() callback and is used 391 + * to provide the resource table for a booted DSP in IPC-only mode. The K3 DSP 392 + * firmwares follow a design-by-contract approach and are expected to have the 393 + * resource table at the base of the DDR region reserved for firmware usage. 394 + * This provides flexibility for the remote processor to be booted by different 395 + * bootloaders that may or may not have the ability to publish the resource table 396 + * address and size through a DT property. This callback is invoked only in 397 + * IPC-only mode. 398 + */ 399 + static struct resource_table *k3_dsp_get_loaded_rsc_table(struct rproc *rproc, 400 + size_t *rsc_table_sz) 401 + { 402 + struct k3_dsp_rproc *kproc = rproc->priv; 403 + struct device *dev = kproc->dev; 404 + 405 + if (!kproc->rmem[0].cpu_addr) { 406 + dev_err(dev, "memory-region #1 does not exist, loaded rsc table can't be found"); 407 + return ERR_PTR(-ENOMEM); 408 + } 409 + 410 + /* 411 + * NOTE: The resource table size is currently hard-coded to a maximum 412 + * of 256 bytes. The most common resource table usage for K3 firmwares 413 + * is to only have the vdev resource entry and an optional trace entry. 414 + * The exact size could be computed based on resource table address, but 415 + * the hard-coded value suffices to support the IPC-only mode. 416 + */ 417 + *rsc_table_sz = 256; 418 + return (struct resource_table *)kproc->rmem[0].cpu_addr; 361 419 } 362 420 363 421 /* ··· 678 592 struct k3_dsp_rproc *kproc; 679 593 struct rproc *rproc; 680 594 const char *fw_name; 595 + bool p_state = false; 681 596 int ret = 0; 682 597 int ret1; 683 598 ··· 757 670 goto release_tsp; 758 671 } 759 672 760 - /* 761 - * ensure the DSP local reset is asserted to ensure the DSP doesn't 762 - * execute bogus code in .prepare() when the module reset is released. 763 - */ 764 - if (data->uses_lreset) { 765 - ret = reset_control_status(kproc->reset); 766 - if (ret < 0) { 767 - dev_err(dev, "failed to get reset status, status = %d\n", 768 - ret); 769 - goto release_mem; 770 - } else if (ret == 0) { 771 - dev_warn(dev, "local reset is deasserted for device\n"); 772 - k3_dsp_rproc_reset(kproc); 673 + ret = kproc->ti_sci->ops.dev_ops.is_on(kproc->ti_sci, kproc->ti_sci_id, 674 + NULL, &p_state); 675 + if (ret) { 676 + dev_err(dev, "failed to get initial state, mode cannot be determined, ret = %d\n", 677 + ret); 678 + goto release_mem; 679 + } 680 + 681 + /* configure J721E devices for either remoteproc or IPC-only mode */ 682 + if (p_state) { 683 + dev_info(dev, "configured DSP for IPC-only mode\n"); 684 + rproc->state = RPROC_DETACHED; 685 + /* override rproc ops with only required IPC-only mode ops */ 686 + rproc->ops->prepare = NULL; 687 + rproc->ops->unprepare = NULL; 688 + rproc->ops->start = NULL; 689 + rproc->ops->stop = NULL; 690 + rproc->ops->attach = k3_dsp_rproc_attach; 691 + rproc->ops->detach = k3_dsp_rproc_detach; 692 + rproc->ops->get_loaded_rsc_table = k3_dsp_get_loaded_rsc_table; 693 + } else { 694 + dev_info(dev, "configured DSP for remoteproc mode\n"); 695 + /* 696 + * ensure the DSP local reset is asserted to ensure the DSP 697 + * doesn't execute bogus code in .prepare() when the module 698 + * reset is released. 699 + */ 700 + if (data->uses_lreset) { 701 + ret = reset_control_status(kproc->reset); 702 + if (ret < 0) { 703 + dev_err(dev, "failed to get reset status, status = %d\n", 704 + ret); 705 + goto release_mem; 706 + } else if (ret == 0) { 707 + dev_warn(dev, "local reset is deasserted for device\n"); 708 + k3_dsp_rproc_reset(kproc); 709 + } 773 710 } 774 711 } 775 712 ··· 828 717 static int k3_dsp_rproc_remove(struct platform_device *pdev) 829 718 { 830 719 struct k3_dsp_rproc *kproc = platform_get_drvdata(pdev); 720 + struct rproc *rproc = kproc->rproc; 831 721 struct device *dev = &pdev->dev; 832 722 int ret; 723 + 724 + if (rproc->state == RPROC_ATTACHED) { 725 + ret = rproc_detach(rproc); 726 + if (ret) { 727 + dev_err(dev, "failed to detach proc, ret = %d\n", ret); 728 + return ret; 729 + } 730 + } 833 731 834 732 rproc_del(kproc->rproc); 835 733
+256 -31
drivers/remoteproc/ti_k3_r5_remoteproc.c
··· 2 2 /* 3 3 * TI K3 R5F (MCU) Remote Processor driver 4 4 * 5 - * Copyright (C) 2017-2020 Texas Instruments Incorporated - https://www.ti.com/ 5 + * Copyright (C) 2017-2022 Texas Instruments Incorporated - https://www.ti.com/ 6 6 * Suman Anna <s-anna@ti.com> 7 7 */ 8 8 ··· 376 376 0, PROC_BOOT_CTRL_FLAG_R5_CORE_HALT); 377 377 } 378 378 379 + static int k3_r5_rproc_request_mbox(struct rproc *rproc) 380 + { 381 + struct k3_r5_rproc *kproc = rproc->priv; 382 + struct mbox_client *client = &kproc->client; 383 + struct device *dev = kproc->dev; 384 + int ret; 385 + 386 + client->dev = dev; 387 + client->tx_done = NULL; 388 + client->rx_callback = k3_r5_rproc_mbox_callback; 389 + client->tx_block = false; 390 + client->knows_txdone = false; 391 + 392 + kproc->mbox = mbox_request_channel(client, 0); 393 + if (IS_ERR(kproc->mbox)) { 394 + ret = -EBUSY; 395 + dev_err(dev, "mbox_request_channel failed: %ld\n", 396 + PTR_ERR(kproc->mbox)); 397 + return ret; 398 + } 399 + 400 + /* 401 + * Ping the remote processor, this is only for sanity-sake for now; 402 + * there is no functional effect whatsoever. 403 + * 404 + * Note that the reply will _not_ arrive immediately: this message 405 + * will wait in the mailbox fifo until the remote processor is booted. 406 + */ 407 + ret = mbox_send_message(kproc->mbox, (void *)RP_MBOX_ECHO_REQUEST); 408 + if (ret < 0) { 409 + dev_err(dev, "mbox_send_message failed: %d\n", ret); 410 + mbox_free_channel(kproc->mbox); 411 + return ret; 412 + } 413 + 414 + return 0; 415 + } 416 + 379 417 /* 380 418 * The R5F cores have controls for both a reset and a halt/run. The code 381 419 * execution from DDR requires the initial boot-strapping code to be run ··· 428 390 * private to each core. Only Core0 needs to be unhalted for running the 429 391 * cluster in this mode. The function uses the same reset logic as LockStep 430 392 * mode for this (though the behavior is agnostic of the reset release order). 393 + * This callback is invoked only in remoteproc mode. 431 394 */ 432 395 static int k3_r5_rproc_prepare(struct rproc *rproc) 433 396 { ··· 494 455 * both cores. The access is made possible only with releasing the resets for 495 456 * both cores, but with only Core0 unhalted. This function re-uses the same 496 457 * reset assert logic as LockStep mode for this mode (though the behavior is 497 - * agnostic of the reset assert order). 458 + * agnostic of the reset assert order). This callback is invoked only in 459 + * remoteproc mode. 498 460 */ 499 461 static int k3_r5_rproc_unprepare(struct rproc *rproc) 500 462 { ··· 529 489 * 530 490 * The Single-CPU mode on applicable SoCs (eg: AM64x) only uses Core0 to execute 531 491 * code, so only Core0 needs to be unhalted. The function uses the same logic 532 - * flow as Split-mode for this. 492 + * flow as Split-mode for this. This callback is invoked only in remoteproc 493 + * mode. 533 494 */ 534 495 static int k3_r5_rproc_start(struct rproc *rproc) 535 496 { 536 497 struct k3_r5_rproc *kproc = rproc->priv; 537 498 struct k3_r5_cluster *cluster = kproc->cluster; 538 - struct mbox_client *client = &kproc->client; 539 499 struct device *dev = kproc->dev; 540 500 struct k3_r5_core *core; 541 501 u32 boot_addr; 542 502 int ret; 543 503 544 - client->dev = dev; 545 - client->tx_done = NULL; 546 - client->rx_callback = k3_r5_rproc_mbox_callback; 547 - client->tx_block = false; 548 - client->knows_txdone = false; 549 - 550 - kproc->mbox = mbox_request_channel(client, 0); 551 - if (IS_ERR(kproc->mbox)) { 552 - ret = -EBUSY; 553 - dev_err(dev, "mbox_request_channel failed: %ld\n", 554 - PTR_ERR(kproc->mbox)); 504 + ret = k3_r5_rproc_request_mbox(rproc); 505 + if (ret) 555 506 return ret; 556 - } 557 - 558 - /* 559 - * Ping the remote processor, this is only for sanity-sake for now; 560 - * there is no functional effect whatsoever. 561 - * 562 - * Note that the reply will _not_ arrive immediately: this message 563 - * will wait in the mailbox fifo until the remote processor is booted. 564 - */ 565 - ret = mbox_send_message(kproc->mbox, (void *)RP_MBOX_ECHO_REQUEST); 566 - if (ret < 0) { 567 - dev_err(dev, "mbox_send_message failed: %d\n", ret); 568 - goto put_mbox; 569 - } 570 507 571 508 boot_addr = rproc->bootaddr; 572 509 /* TODO: add boot_addr sanity checking */ ··· 601 584 * be done here, but is preferred to be done in the .unprepare() ops - this 602 585 * maintains the symmetric behavior between the .start(), .stop(), .prepare() 603 586 * and .unprepare() ops, and also balances them well between sysfs 'state' 604 - * flow and device bind/unbind or module removal. 587 + * flow and device bind/unbind or module removal. This callback is invoked 588 + * only in remoteproc mode. 605 589 */ 606 590 static int k3_r5_rproc_stop(struct rproc *rproc) 607 591 { ··· 637 619 } 638 620 out: 639 621 return ret; 622 + } 623 + 624 + /* 625 + * Attach to a running R5F remote processor (IPC-only mode) 626 + * 627 + * The R5F attach callback only needs to request the mailbox, the remote 628 + * processor is already booted, so there is no need to issue any TI-SCI 629 + * commands to boot the R5F cores in IPC-only mode. This callback is invoked 630 + * only in IPC-only mode. 631 + */ 632 + static int k3_r5_rproc_attach(struct rproc *rproc) 633 + { 634 + struct k3_r5_rproc *kproc = rproc->priv; 635 + struct device *dev = kproc->dev; 636 + int ret; 637 + 638 + ret = k3_r5_rproc_request_mbox(rproc); 639 + if (ret) 640 + return ret; 641 + 642 + dev_info(dev, "R5F core initialized in IPC-only mode\n"); 643 + return 0; 644 + } 645 + 646 + /* 647 + * Detach from a running R5F remote processor (IPC-only mode) 648 + * 649 + * The R5F detach callback performs the opposite operation to attach callback 650 + * and only needs to release the mailbox, the R5F cores are not stopped and 651 + * will be left in booted state in IPC-only mode. This callback is invoked 652 + * only in IPC-only mode. 653 + */ 654 + static int k3_r5_rproc_detach(struct rproc *rproc) 655 + { 656 + struct k3_r5_rproc *kproc = rproc->priv; 657 + struct device *dev = kproc->dev; 658 + 659 + mbox_free_channel(kproc->mbox); 660 + dev_info(dev, "R5F core deinitialized in IPC-only mode\n"); 661 + return 0; 662 + } 663 + 664 + /* 665 + * This function implements the .get_loaded_rsc_table() callback and is used 666 + * to provide the resource table for the booted R5F in IPC-only mode. The K3 R5F 667 + * firmwares follow a design-by-contract approach and are expected to have the 668 + * resource table at the base of the DDR region reserved for firmware usage. 669 + * This provides flexibility for the remote processor to be booted by different 670 + * bootloaders that may or may not have the ability to publish the resource table 671 + * address and size through a DT property. This callback is invoked only in 672 + * IPC-only mode. 673 + */ 674 + static struct resource_table *k3_r5_get_loaded_rsc_table(struct rproc *rproc, 675 + size_t *rsc_table_sz) 676 + { 677 + struct k3_r5_rproc *kproc = rproc->priv; 678 + struct device *dev = kproc->dev; 679 + 680 + if (!kproc->rmem[0].cpu_addr) { 681 + dev_err(dev, "memory-region #1 does not exist, loaded rsc table can't be found"); 682 + return ERR_PTR(-ENOMEM); 683 + } 684 + 685 + /* 686 + * NOTE: The resource table size is currently hard-coded to a maximum 687 + * of 256 bytes. The most common resource table usage for K3 firmwares 688 + * is to only have the vdev resource entry and an optional trace entry. 689 + * The exact size could be computed based on resource table address, but 690 + * the hard-coded value suffices to support the IPC-only mode. 691 + */ 692 + *rsc_table_sz = 256; 693 + return (struct resource_table *)kproc->rmem[0].cpu_addr; 640 694 } 641 695 642 696 /* ··· 1090 1000 } 1091 1001 } 1092 1002 1003 + /* 1004 + * This function checks and configures a R5F core for IPC-only or remoteproc 1005 + * mode. The driver is configured to be in IPC-only mode for a R5F core when 1006 + * the core has been loaded and started by a bootloader. The IPC-only mode is 1007 + * detected by querying the System Firmware for reset, power on and halt status 1008 + * and ensuring that the core is running. Any incomplete steps at bootloader 1009 + * are validated and errored out. 1010 + * 1011 + * In IPC-only mode, the driver state flags for ATCM, BTCM and LOCZRAMA settings 1012 + * and cluster mode parsed originally from kernel DT are updated to reflect the 1013 + * actual values configured by bootloader. The driver internal device memory 1014 + * addresses for TCMs are also updated. 1015 + */ 1016 + static int k3_r5_rproc_configure_mode(struct k3_r5_rproc *kproc) 1017 + { 1018 + struct k3_r5_cluster *cluster = kproc->cluster; 1019 + struct k3_r5_core *core = kproc->core; 1020 + struct device *cdev = core->dev; 1021 + bool r_state = false, c_state = false; 1022 + u32 ctrl = 0, cfg = 0, stat = 0, halted = 0; 1023 + u64 boot_vec = 0; 1024 + u32 atcm_enable, btcm_enable, loczrama; 1025 + struct k3_r5_core *core0; 1026 + enum cluster_mode mode; 1027 + int ret; 1028 + 1029 + core0 = list_first_entry(&cluster->cores, struct k3_r5_core, elem); 1030 + 1031 + ret = core->ti_sci->ops.dev_ops.is_on(core->ti_sci, core->ti_sci_id, 1032 + &r_state, &c_state); 1033 + if (ret) { 1034 + dev_err(cdev, "failed to get initial state, mode cannot be determined, ret = %d\n", 1035 + ret); 1036 + return ret; 1037 + } 1038 + if (r_state != c_state) { 1039 + dev_warn(cdev, "R5F core may have been powered on by a different host, programmed state (%d) != actual state (%d)\n", 1040 + r_state, c_state); 1041 + } 1042 + 1043 + ret = reset_control_status(core->reset); 1044 + if (ret < 0) { 1045 + dev_err(cdev, "failed to get initial local reset status, ret = %d\n", 1046 + ret); 1047 + return ret; 1048 + } 1049 + 1050 + ret = ti_sci_proc_get_status(core->tsp, &boot_vec, &cfg, &ctrl, 1051 + &stat); 1052 + if (ret < 0) { 1053 + dev_err(cdev, "failed to get initial processor status, ret = %d\n", 1054 + ret); 1055 + return ret; 1056 + } 1057 + atcm_enable = cfg & PROC_BOOT_CFG_FLAG_R5_ATCM_EN ? 1 : 0; 1058 + btcm_enable = cfg & PROC_BOOT_CFG_FLAG_R5_BTCM_EN ? 1 : 0; 1059 + loczrama = cfg & PROC_BOOT_CFG_FLAG_R5_TCM_RSTBASE ? 1 : 0; 1060 + if (cluster->soc_data->single_cpu_mode) { 1061 + mode = cfg & PROC_BOOT_CFG_FLAG_R5_SINGLE_CORE ? 1062 + CLUSTER_MODE_SINGLECPU : CLUSTER_MODE_SPLIT; 1063 + } else { 1064 + mode = cfg & PROC_BOOT_CFG_FLAG_R5_LOCKSTEP ? 1065 + CLUSTER_MODE_LOCKSTEP : CLUSTER_MODE_SPLIT; 1066 + } 1067 + halted = ctrl & PROC_BOOT_CTRL_FLAG_R5_CORE_HALT; 1068 + 1069 + /* 1070 + * IPC-only mode detection requires both local and module resets to 1071 + * be deasserted and R5F core to be unhalted. Local reset status is 1072 + * irrelevant if module reset is asserted (POR value has local reset 1073 + * deasserted), and is deemed as remoteproc mode 1074 + */ 1075 + if (c_state && !ret && !halted) { 1076 + dev_info(cdev, "configured R5F for IPC-only mode\n"); 1077 + kproc->rproc->state = RPROC_DETACHED; 1078 + ret = 1; 1079 + /* override rproc ops with only required IPC-only mode ops */ 1080 + kproc->rproc->ops->prepare = NULL; 1081 + kproc->rproc->ops->unprepare = NULL; 1082 + kproc->rproc->ops->start = NULL; 1083 + kproc->rproc->ops->stop = NULL; 1084 + kproc->rproc->ops->attach = k3_r5_rproc_attach; 1085 + kproc->rproc->ops->detach = k3_r5_rproc_detach; 1086 + kproc->rproc->ops->get_loaded_rsc_table = 1087 + k3_r5_get_loaded_rsc_table; 1088 + } else if (!c_state) { 1089 + dev_info(cdev, "configured R5F for remoteproc mode\n"); 1090 + ret = 0; 1091 + } else { 1092 + dev_err(cdev, "mismatched mode: local_reset = %s, module_reset = %s, core_state = %s\n", 1093 + !ret ? "deasserted" : "asserted", 1094 + c_state ? "deasserted" : "asserted", 1095 + halted ? "halted" : "unhalted"); 1096 + ret = -EINVAL; 1097 + } 1098 + 1099 + /* fixup TCMs, cluster & core flags to actual values in IPC-only mode */ 1100 + if (ret > 0) { 1101 + if (core == core0) 1102 + cluster->mode = mode; 1103 + core->atcm_enable = atcm_enable; 1104 + core->btcm_enable = btcm_enable; 1105 + core->loczrama = loczrama; 1106 + core->mem[0].dev_addr = loczrama ? 0 : K3_R5_TCM_DEV_ADDR; 1107 + core->mem[1].dev_addr = loczrama ? K3_R5_TCM_DEV_ADDR : 0; 1108 + } 1109 + 1110 + return ret; 1111 + } 1112 + 1093 1113 static int k3_r5_cluster_rproc_init(struct platform_device *pdev) 1094 1114 { 1095 1115 struct k3_r5_cluster *cluster = platform_get_drvdata(pdev); ··· 1209 1009 struct device *cdev; 1210 1010 const char *fw_name; 1211 1011 struct rproc *rproc; 1212 - int ret; 1012 + int ret, ret1; 1213 1013 1214 1014 core1 = list_last_entry(&cluster->cores, struct k3_r5_core, elem); 1215 1015 list_for_each_entry(core, &cluster->cores, elem) { ··· 1240 1040 kproc->rproc = rproc; 1241 1041 core->rproc = rproc; 1242 1042 1043 + ret = k3_r5_rproc_configure_mode(kproc); 1044 + if (ret < 0) 1045 + goto err_config; 1046 + if (ret) 1047 + goto init_rmem; 1048 + 1243 1049 ret = k3_r5_rproc_configure(kproc); 1244 1050 if (ret) { 1245 1051 dev_err(dev, "initial configure failed, ret = %d\n", ··· 1253 1047 goto err_config; 1254 1048 } 1255 1049 1050 + init_rmem: 1256 1051 k3_r5_adjust_tcm_sizes(kproc); 1257 1052 1258 1053 ret = k3_r5_reserved_mem_init(kproc); ··· 1278 1071 return 0; 1279 1072 1280 1073 err_split: 1074 + if (rproc->state == RPROC_ATTACHED) { 1075 + ret1 = rproc_detach(rproc); 1076 + if (ret1) { 1077 + dev_err(kproc->dev, "failed to detach rproc, ret = %d\n", 1078 + ret1); 1079 + return ret1; 1080 + } 1081 + } 1082 + 1281 1083 rproc_del(rproc); 1282 1084 err_add: 1283 1085 k3_r5_reserved_mem_exit(kproc); ··· 1310 1094 struct k3_r5_rproc *kproc; 1311 1095 struct k3_r5_core *core; 1312 1096 struct rproc *rproc; 1097 + int ret; 1313 1098 1314 1099 /* 1315 1100 * lockstep mode and single-cpu modes have only one rproc associated ··· 1325 1108 list_for_each_entry_from_reverse(core, &cluster->cores, elem) { 1326 1109 rproc = core->rproc; 1327 1110 kproc = rproc->priv; 1111 + 1112 + if (rproc->state == RPROC_ATTACHED) { 1113 + ret = rproc_detach(rproc); 1114 + if (ret) { 1115 + dev_err(kproc->dev, "failed to detach rproc, ret = %d\n", ret); 1116 + return; 1117 + } 1118 + } 1328 1119 1329 1120 rproc_del(rproc); 1330 1121
+1
drivers/remoteproc/wkup_m3_rproc.c
··· 163 163 } 164 164 165 165 rproc->auto_boot = false; 166 + rproc->sysfs_read_only = true; 166 167 167 168 wkupm3 = rproc->priv; 168 169 wkupm3->rproc = rproc;
+4 -1
include/linux/remoteproc.h
··· 523 523 * @table_sz: size of @cached_table 524 524 * @has_iommu: flag to indicate if remote processor is behind an MMU 525 525 * @auto_boot: flag to indicate if remote processor should be auto-started 526 + * @sysfs_read_only: flag to make remoteproc sysfs files read only 526 527 * @dump_segments: list of segments in the firmware 527 528 * @nb_vdev: number of vdev currently handled by rproc 528 529 * @elf_class: firmware ELF class ··· 563 562 size_t table_sz; 564 563 bool has_iommu; 565 564 bool auto_boot; 565 + bool sysfs_read_only; 566 566 struct list_head dump_segments; 567 567 int nb_vdev; 568 568 u8 elf_class; ··· 671 669 u32 da, const char *name, ...); 672 670 673 671 int rproc_boot(struct rproc *rproc); 674 - void rproc_shutdown(struct rproc *rproc); 672 + int rproc_shutdown(struct rproc *rproc); 675 673 int rproc_detach(struct rproc *rproc); 676 674 int rproc_set_firmware(struct rproc *rproc, const char *fw_name); 677 675 void rproc_report_crash(struct rproc *rproc, enum rproc_crash_type type); 676 + void *rproc_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem); 678 677 void rproc_coredump_using_sections(struct rproc *rproc); 679 678 int rproc_coredump_add_segment(struct rproc *rproc, dma_addr_t da, size_t size); 680 679 int rproc_coredump_add_custom_segment(struct rproc *rproc,