History

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

Pull remoteproc updates from Bjorn Andersson: - Add i.MX94 support to the i.MX remoteproc driver, covering the Cortex-M7 and Cortex-M33 Sync cores. This also fixes programming of non-zero System Manager CPU/LMM reset vectors. - Move the remoteproc resource table definitions to a separate header, so they can be used by clients that do not otherwise depend on remoteproc. Switch the firmware resource handling over to the common iterator. - Update the Xilinx R5F remoteproc driver to check the remote core state before attaching, drop a binding header dependency, and add firmware-name based auto boot support. - Add Qualcomm Hawi ADSP/CDSP bindings, together with Shikra RPM bindings and CDSP, LPAICP, and MPSS PAS support. Fix a Qualcomm minidump leak, clean up PAS and WCSS reset handling, and make the user-visible Qualcomm naming consistent. - Remove a duplicate STM32_RPROC Kconfig dependency and make i.MX remoteproc instances use the device node name so multiple processors can be distinguished in sysfs. * tag 'rproc-v7.2' of git://git.kernel.org/pub/scm/linux/kernel/git/remoteproc/linux: remoteproc: qcom: pas: Drop start/stop completion from struct qcom_pas remoteproc: qcom: pas: Add Shikra remoteproc support dt-bindings: remoteproc: qcom,shikra-pas: Document Shikra PAS remoteprocs dt-bindings: remoteproc: Add Shikra RPM processor compatible remoteproc: qcom: Unify user-visible "Qualcomm" name remoteproc: qcom: Fix leak when custom dump_segments addition fails remoteproc: qcom_q6v5_wcss: drop redundant wcss_q6_bcr_reset dt-bindings: remoteproc: qcom,sm8550-pas: Add Hawi CDSP compatible dt-bindings: remoteproc: qcom,sm8550-pas: Add Hawi ADSP compatible remoteproc: xlnx: Enable auto boot feature dt-bindings: remoteproc: xlnx: Add firmware-name property remoteproc: xlnx: Remove binding header dependency remoteproc: imx_rproc: Use device node name as processor name remoteproc: use rsc_table_for_each_entry() in rproc_handle_resources() remoteproc: Move resource table data structure to its own header remoteproc: xlnx: Check remote core state remoteproc: imx_rproc: Add support for i.MX94 remoteproc: imx_rproc: Program non-zero SM CPU/LMM reset vector dt-bindings: remoteproc: imx-rproc: Support i.MX94 remoteproc: Dead code cleanup in Kconfig for STM32_RPROC

Linus Torvalds committed 4 months ago

Commit 9d0d4d12 parents 390d73a b5bfc7d17 files · +858 −367Browse files

Unified · Split

17 files
  1. Documentation/devicetree/bindings/remoteproc/fsl,imx-rproc.yaml +3 −0
  2. Documentation/devicetree/bindings/remoteproc/qcom,rpm-proc.yaml +1 −0
  3. Documentation/devicetree/bindings/remoteproc/qcom,shikra-pas.yaml +167 −0
  4. Documentation/devicetree/bindings/remoteproc/qcom,sm8550-pas.yaml +4 −0
  5. Documentation/devicetree/bindings/remoteproc/xlnx,zynqmp-r5fss.yaml +4 −0
  6. drivers/firmware/xilinx/zynqmp.c +28 −0
  7. drivers/remoteproc/Kconfig +1 −2
  8. drivers/remoteproc/imx_rproc.c +91 −4
  9. drivers/remoteproc/imx_rproc.h +2 −0
  10. drivers/remoteproc/qcom_common.c +10 −4
  11. drivers/remoteproc/qcom_q6v5_pas.c +48 −3
  12. drivers/remoteproc/qcom_q6v5_wcss.c +5 −18
  13. drivers/remoteproc/remoteproc_core.c +38 −43
  14. drivers/remoteproc/xlnx_r5_remoteproc.c +75 −25
  15. include/linux/firmware/xlnx-zynqmp.h +21 −0
  16. include/linux/remoteproc.h +1 −268
  17. include/linux/rsc_table.h +359 −0
Documentation/devicetree/bindings/remoteproc/fsl,imx-rproc.yaml+3−0
@@ -28,6 +28,9 @@ properties: · 27 unmodified lines
28 - fsl,imx8qxp-cm428 - fsl,imx8qxp-cm4
29 - fsl,imx8ulp-cm3329 - fsl,imx8ulp-cm33
30 - fsl,imx93-cm3330 - fsl,imx93-cm33
31 - fsl,imx94-cm33s
32 - fsl,imx94-cm70
33 - fsl,imx94-cm71
31 - fsl,imx95-cm734 - fsl,imx95-cm7
32 35
33 clocks:36 clocks:
Documentation/devicetree/bindings/remoteproc/qcom,rpm-proc.yaml+1−0
@@ -87,6 +87,7 @@ properties: · 86 unmodified lines
87 - qcom,qcm2290-rpm-proc87 - qcom,qcm2290-rpm-proc
88 - qcom,qcs404-rpm-proc88 - qcom,qcs404-rpm-proc
89 - qcom,sdm660-rpm-proc89 - qcom,sdm660-rpm-proc
90 - qcom,shikra-rpm-proc
90 - qcom,sm6115-rpm-proc91 - qcom,sm6115-rpm-proc
91 - qcom,sm6125-rpm-proc92 - qcom,sm6125-rpm-proc
92 - qcom,sm6375-rpm-proc93 - qcom,sm6375-rpm-proc
Documentation/devicetree/bindings/remoteproc/qcom,shikra-pas.yaml+167−0
@@ -0,0 +1,167 @@
1# SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
2%YAML 1.2
3---
4$id: http://devicetree.org/schemas/remoteproc/qcom,shikra-pas.yaml#
5$schema: http://devicetree.org/meta-schemas/core.yaml#
6
7title: Qualcomm Shikra SoC Peripheral Authentication Service
8
9maintainers:
10 - Bibek Kumar Patro <bibek.patro@oss.qualcomm.com>
11 - Komal Bajaj <komal.bajaj@oss.qualcomm.com>
12
13description:
14 Qualcomm Shikra SoC Peripheral Authentication Service loads and boots
15 firmware on the Qualcomm DSP Hexagon cores.
16
17properties:
18 compatible:
19 enum:
20 - qcom,shikra-cdsp-pas
21 - qcom,shikra-lpaicp-pas
22 - qcom,shikra-mpss-pas
23
24 reg:
25 maxItems: 1
26
27 clocks:
28 items:
29 - description: XO clock
30
31 clock-names:
32 items:
33 - const: xo
34
35 memory-region:
36 minItems: 1
37 maxItems: 2
38
39 smd-edge: false
40
41 firmware-name:
42 minItems: 1
43 items:
44 - description: Firmware name of the Hexagon core
45 - description: Firmware name of the Hexagon Devicetree
46
47 glink-edge:
48 $ref: /schemas/remoteproc/qcom,glink-edge.yaml#
49 description:
50 Qualcomm G-Link subnode which represents communication edge, channels
51 and devices related to the remoteproc core.
52 unevaluatedProperties: false
53
54 qcom,smem-states:
55 $ref: /schemas/types.yaml#/definitions/phandle-array
56 description: States used by the AP to signal the Hexagon core
57 items:
58 - description: Stop the remote processor
59 items:
60 - description: Phandle to the Shared Memory Point 2 Point device
61 handling the communication with a remote processor
62 - description: Single bit index to toggle in the value sent to
63 the remote processor
64 maximum: 32
65
66 qcom,smem-state-names:
67 description: The names of the state bits used for SMP2P output
68 items:
69 - const: stop
70
71required:
72 - compatible
73 - reg
74 - memory-region
75
76allOf:
77 - $ref: /schemas/remoteproc/qcom,pas-common.yaml#
78
79 - if:
80 properties:
81 compatible:
82 enum:
83 - qcom,shikra-cdsp-pas
84 - qcom,shikra-mpss-pas
85 then:
86 properties:
87 interrupts:
88 minItems: 6
89 interrupt-names:
90 minItems: 6
91 memory-region:
92 maxItems: 1
93 firmware-name:
94 maxItems: 1
95 power-domains:
96 items:
97 - description: CX power domain
98 power-domain-names:
99 items:
100 - const: cx
101
102 - if:
103 properties:
104 compatible:
105 enum:
106 - qcom,shikra-lpaicp-pas
107 then:
108 properties:
109 interrupts:
110 maxItems: 5
111 interrupt-names:
112 maxItems: 5
113 memory-region:
114 minItems: 2
115 firmware-name:
116 minItems: 2
117 power-domains: false
118 power-domain-names: false
119
120unevaluatedProperties: false
121
122examples:
123 - |
124 #include <dt-bindings/clock/qcom,rpmcc.h>
125 #include <dt-bindings/interconnect/qcom,icc.h>
126 #include <dt-bindings/interconnect/qcom,rpm-icc.h>
127 #include <dt-bindings/interconnect/qcom,shikra.h>
128 #include <dt-bindings/interrupt-controller/arm-gic.h>
129 #include <dt-bindings/interrupt-controller/irq.h>
130 #include <dt-bindings/power/qcom-rpmpd.h>
131
132 remoteproc@b300000 {
133 compatible = "qcom,shikra-cdsp-pas";
134 reg = <0x0b300000 0x100000>;
135
136 interrupts-extended = <&intc GIC_SPI 265 IRQ_TYPE_EDGE_RISING>,
137 <&cdsp_smp2p_in 0 IRQ_TYPE_EDGE_RISING>,
138 <&cdsp_smp2p_in 1 IRQ_TYPE_EDGE_RISING>,
139 <&cdsp_smp2p_in 2 IRQ_TYPE_EDGE_RISING>,
140 <&cdsp_smp2p_in 3 IRQ_TYPE_EDGE_RISING>,
141 <&cdsp_smp2p_in 7 IRQ_TYPE_EDGE_RISING>;
142 interrupt-names = "wdog", "fatal", "ready",
143 "handover", "stop-ack", "shutdown-ack";
144
145 clocks = <&rpmcc RPM_SMD_XO_CLK_SRC>;
146 clock-names = "xo";
147
148 interconnects = <&mem_noc MASTER_AMPSS_M0 RPM_ALWAYS_TAG
149 &mc_virt SLAVE_EBI_CH0 RPM_ALWAYS_TAG>;
150
151 power-domains = <&rpmpd RPMHPD_CX>;
152 power-domain-names = "cx";
153
154 memory-region = <&cdsp_mem>;
155
156 qcom,smem-states = <&cdsp_smp2p_out 0>;
157 qcom,smem-state-names = "stop";
158
159 firmware-name = "qcom/shikra/cdsp.mbn";
160
161 glink-edge {
162 interrupts = <GIC_SPI 261 IRQ_TYPE_EDGE_RISING>;
163 mboxes = <&apcs_glb 4>;
164 qcom,remote-pid = <5>;
165 label = "cdsp";
166 };
167 };
Documentation/devicetree/bindings/remoteproc/qcom,sm8550-pas.yaml+4−0
@@ -30,12 +30,14 @@ properties: · 29 unmodified lines
30 - items:30 - items:
31 - enum:31 - enum:
32 - qcom,glymur-adsp-pas32 - qcom,glymur-adsp-pas
33 - qcom,hawi-adsp-pas
33 - qcom,kaanapali-adsp-pas34 - qcom,kaanapali-adsp-pas
34 - qcom,sm8750-adsp-pas35 - qcom,sm8750-adsp-pas
35 - const: qcom,sm8550-adsp-pas36 - const: qcom,sm8550-adsp-pas
36 - items:37 - items:
37 - enum:38 - enum:
38 - qcom,glymur-cdsp-pas39 - qcom,glymur-cdsp-pas
40 - qcom,hawi-cdsp-pas
39 - qcom,kaanapali-cdsp-pas41 - qcom,kaanapali-cdsp-pas
40 - const: qcom,sm8550-cdsp-pas42 - const: qcom,sm8550-cdsp-pas
41 - items:43 - items:
@@ -104,6 +106,8 @@ allOf: · 62 unmodified lines
104 enum:106 enum:
105 - qcom,glymur-adsp-pas107 - qcom,glymur-adsp-pas
106 - qcom,glymur-cdsp-pas108 - qcom,glymur-cdsp-pas
109 - qcom,hawi-adsp-pas
110 - qcom,hawi-cdsp-pas
107 - qcom,kaanapali-adsp-pas111 - qcom,kaanapali-adsp-pas
108 - qcom,kaanapali-cdsp-pas112 - qcom,kaanapali-cdsp-pas
109 - qcom,sm8750-adsp-pas113 - qcom,sm8750-adsp-pas
Documentation/devicetree/bindings/remoteproc/xlnx,zynqmp-r5fss.yaml+4−0
@@ -128,6 +128,10 @@ patternProperties: · 127 unmodified lines
128 - description: vring1128 - description: vring1
129 additionalItems: true129 additionalItems: true
130 130
131 firmware-name:
132 maxItems: 1
133 description: default firmware to load
134
131 required:135 required:
132 - compatible136 - compatible
133 - reg137 - reg
drivers/firmware/xilinx/zynqmp.c+28−0
@@ -1450,6 +1450,34 @@ int zynqmp_pm_get_node_status(const u32 node, u32 *const status, · 1449 unmodified lines
1450}1450}
1451EXPORT_SYMBOL_GPL(zynqmp_pm_get_node_status);1451EXPORT_SYMBOL_GPL(zynqmp_pm_get_node_status);
1452 1452
1453/**
1454 * zynqmp_pm_get_rpu_node_status - PM call to request a RPU node's current power state
1455 * @node: ID of the RPU component or sub-system in question
1456 * @status: Current operating state of the requested RPU node.
1457 * @requirements: Current requirements asserted on the RPU node.
1458 * @usage: Usage information, used for RPU slave nodes only:
1459 * PM_USAGE_NO_MASTER - No master is currently using
1460 * the node
1461 * PM_USAGE_CURRENT_MASTER - Only requesting master is
1462 * currently using the node
1463 * PM_USAGE_OTHER_MASTER - Only other masters are
1464 * currently using the node
1465 * PM_USAGE_BOTH_MASTERS - Both the current and at least
1466 * one other master is currently
1467 * using the node
1468 *
1469 * Return: Returns status, either success or error+reason
1470 */
1471int zynqmp_pm_get_rpu_node_status(const u32 node, u32 *const status,
1472 u32 *const requirements, u32 *const usage)
1473{
1474 if (zynqmp_pm_feature(PM_GET_NODE_STATUS) < PM_API_VERSION_2)
1475 return -EOPNOTSUPP;
1476
1477 return zynqmp_pm_get_node_status(node, status, requirements, usage);
1478}
1479EXPORT_SYMBOL_GPL(zynqmp_pm_get_rpu_node_status);
1480
1453/**1481/**
1454 * zynqmp_pm_force_pwrdwn - PM call to request for another PU or subsystem to1482 * zynqmp_pm_force_pwrdwn - PM call to request for another PU or subsystem to
1455 * be powered down forcefully1483 * be powered down forcefully
drivers/remoteproc/Kconfig+1−2
@@ -176,7 +176,7 @@ config QCOM_Q6V5_COMMON · 175 unmodified lines
176 depends on QCOM_SMEM176 depends on QCOM_SMEM
177 177
178config QCOM_Q6V5_ADSP178config QCOM_Q6V5_ADSP
179 tristate "Qualcomm Technology Inc ADSP Peripheral Image Loader"179 tristate "Qualcomm ADSP Peripheral Image Loader"
180 depends on OF && ARCH_QCOM180 depends on OF && ARCH_QCOM
181 depends on QCOM_SMEM181 depends on QCOM_SMEM
182 depends on RPMSG_QCOM_SMD || RPMSG_QCOM_SMD=n182 depends on RPMSG_QCOM_SMD || RPMSG_QCOM_SMD=n
@@ -316,7 +316,6 @@ config ST_SLIM_REMOTEPROC · 133 unmodified lines
316config STM32_RPROC316config STM32_RPROC
317 tristate "STM32 remoteproc support"317 tristate "STM32 remoteproc support"
318 depends on ARCH_STM32 || COMPILE_TEST318 depends on ARCH_STM32 || COMPILE_TEST
319 depends on REMOTEPROC
320 select MAILBOX319 select MAILBOX
321 help320 help
322 Say y here to support STM32 MCU processors via the321 Say y here to support STM32 MCU processors via the
drivers/remoteproc/imx_rproc.c+91−4
@@ -145,6 +145,41 @@ static const struct imx_rproc_att imx_rproc_att_imx95_m7[] = { · 144 unmodified lines
145 { 0x80000000, 0x80000000, 0x50000000, 0 },145 { 0x80000000, 0x80000000, 0x50000000, 0 },
146};146};
147 147
148static const struct imx_rproc_att imx_rproc_att_imx94_m70[] = {
149 /* dev addr , sys addr , size , flags */
150 /* TCM CODE NON-SECURE */
151 { 0x00000000, 0x203C0000, 0x00040000, ATT_OWN | ATT_IOMEM },
152 /* TCM SYS NON-SECURE*/
153 { 0x20000000, 0x20400000, 0x00040000, ATT_OWN | ATT_IOMEM },
154
155 /* DDR */
156 { 0x80000000, 0x80000000, 0x10000000, 0 },
157};
158
159static const struct imx_rproc_att imx_rproc_att_imx94_m71[] = {
160 /* dev addr , sys addr , size , flags */
161 /* TCM CODE NON-SECURE */
162 { 0x00000000, 0x202C0000, 0x00040000, ATT_OWN | ATT_IOMEM },
163 /* TCM SYS NON-SECURE*/
164 { 0x20000000, 0x20300000, 0x00040000, ATT_OWN | ATT_IOMEM },
165
166 /* DDR */
167 { 0x80000000, 0x80000000, 0x10000000, 0 },
168};
169
170static const struct imx_rproc_att imx_rproc_att_imx94_m33s[] = {
171 /* dev addr , sys addr , size , flags */
172 /* TCM CODE NON-SECURE */
173 { 0x0FFC0000, 0x209C0000, 0x00040000, ATT_OWN | ATT_IOMEM },
174 /* TCM SYS NON-SECURE */
175 { 0x20000000, 0x20A00000, 0x00040000, ATT_OWN | ATT_IOMEM },
176 /* M33S OCRAM NON-SECURE */
177 { 0x20800000, 0x20800000, 0x180000, ATT_OWN | ATT_IOMEM },
178
179 /* DDR */
180 { 0x80000000, 0x80000000, 0x10000000, 0 },
181};
182
148static const struct imx_rproc_att imx_rproc_att_imx93[] = {183static const struct imx_rproc_att imx_rproc_att_imx93[] = {
149 /* dev addr , sys addr , size , flags */184 /* dev addr , sys addr , size , flags */
150 /* TCM CODE NON-SECURE */185 /* TCM CODE NON-SECURE */
@@ -339,13 +374,32 @@ static int imx_rproc_scu_api_start(struct rproc *rproc) · 188 unmodified lines
339 return imx_sc_pm_cpu_start(priv->ipc_handle, priv->rsrc_id, true, priv->entry);374 return imx_sc_pm_cpu_start(priv->ipc_handle, priv->rsrc_id, true, priv->entry);
340}375}
341 376
377static u64 imx_rproc_sm_get_reset_vector(struct rproc *rproc)
378{
379 struct imx_rproc *priv = rproc->priv;
380 u32 reset_vector_mask = priv->dcfg->reset_vector_mask ?: GENMASK(31, 0);
381
382 /*
383 * The hardware fetches the first two words from reset_vectors
384 * (hardware reset address) and populates SP and PC using the first
385 * two words. Execution proceeds from PC. The ELF entry point does
386 * not always match the hardware reset address.
387 * To derive the correct hardware reset address, the lower address
388 * bits must be masked off before programming the reset vector.
389 */
390 return rproc->bootaddr & reset_vector_mask;
391}
392
342static int imx_rproc_sm_cpu_start(struct rproc *rproc)393static int imx_rproc_sm_cpu_start(struct rproc *rproc)
343{394{
344 struct imx_rproc *priv = rproc->priv;395 struct imx_rproc *priv = rproc->priv;
345 const struct imx_rproc_dcfg *dcfg = priv->dcfg;396 const struct imx_rproc_dcfg *dcfg = priv->dcfg;
397 u64 reset_vector;
346 int ret;398 int ret;
347 399
348 ret = scmi_imx_cpu_reset_vector_set(dcfg->cpuid, 0, true, false, false);400 reset_vector = imx_rproc_sm_get_reset_vector(rproc);
401
402 ret = scmi_imx_cpu_reset_vector_set(dcfg->cpuid, reset_vector, true, false, false);
349 if (ret) {403 if (ret) {
350 dev_err(priv->dev, "Failed to set reset vector cpuid(%u): %d\n", dcfg->cpuid, ret);404 dev_err(priv->dev, "Failed to set reset vector cpuid(%u): %d\n", dcfg->cpuid, ret);
351 return ret;405 return ret;
@@ -359,13 +413,16 @@ static int imx_rproc_sm_lmm_start(struct rproc *rproc) · 7 unmodified lines
359 struct imx_rproc *priv = rproc->priv;413 struct imx_rproc *priv = rproc->priv;
360 const struct imx_rproc_dcfg *dcfg = priv->dcfg;414 const struct imx_rproc_dcfg *dcfg = priv->dcfg;
361 struct device *dev = priv->dev;415 struct device *dev = priv->dev;
416 u64 reset_vector;
362 int ret;417 int ret;
363 418
419 reset_vector = imx_rproc_sm_get_reset_vector(rproc);
420
364 /*421 /*
365 * If the remoteproc core can't start the M7, it will already be422 * If the remoteproc core can't start the M7, it will already be
366 * handled in imx_rproc_sm_lmm_prepare().423 * handled in imx_rproc_sm_lmm_prepare().
367 */424 */
368 ret = scmi_imx_lmm_reset_vector_set(dcfg->lmid, dcfg->cpuid, 0, 0);425 ret = scmi_imx_lmm_reset_vector_set(dcfg->lmid, dcfg->cpuid, 0, reset_vector);
369 if (ret) {426 if (ret) {
370 dev_err(dev, "Failed to set reset vector lmid(%u), cpuid(%u): %d\n",427 dev_err(dev, "Failed to set reset vector lmid(%u), cpuid(%u): %d\n",
371 dcfg->lmid, dcfg->cpuid, ret);428 dcfg->lmid, dcfg->cpuid, ret);
@@ -1230,8 +1287,7 @@ static int imx_rproc_probe(struct platform_device *pdev) · 858 unmodified lines
1230 const struct imx_rproc_dcfg *dcfg;1287 const struct imx_rproc_dcfg *dcfg;
1231 int ret;1288 int ret;
1232 1289
1233 /* set some other name then imx */1290 rproc = devm_rproc_alloc(dev, np->name, &imx_rproc_ops,
1234 rproc = devm_rproc_alloc(dev, "imx-rproc", &imx_rproc_ops,
1235 NULL, sizeof(*priv));1291 NULL, sizeof(*priv));
1236 if (!rproc)1292 if (!rproc)
1237 return -ENOMEM;1293 return -ENOMEM;
@@ -1455,6 +1511,33 @@ static const struct imx_rproc_dcfg imx_rproc_cfg_imx93 = { · 217 unmodified lines
1455 .flags = IMX_RPROC_NEED_CLKS,1511 .flags = IMX_RPROC_NEED_CLKS,
1456};1512};
1457 1513
1514static const struct imx_rproc_dcfg imx_rproc_cfg_imx94_m70 = {
1515 .att = imx_rproc_att_imx94_m70,
1516 .att_size = ARRAY_SIZE(imx_rproc_att_imx94_m70),
1517 .ops = &imx_rproc_ops_sm_lmm,
1518 .cpuid = 1,
1519 .lmid = 2,
1520 .reset_vector_mask = GENMASK_U32(31, 16),
1521};
1522
1523static const struct imx_rproc_dcfg imx_rproc_cfg_imx94_m71 = {
1524 .att = imx_rproc_att_imx94_m71,
1525 .att_size = ARRAY_SIZE(imx_rproc_att_imx94_m71),
1526 .ops = &imx_rproc_ops_sm_lmm,
1527 .cpuid = 7,
1528 .lmid = 3,
1529 .reset_vector_mask = GENMASK_U32(31, 16),
1530};
1531
1532static const struct imx_rproc_dcfg imx_rproc_cfg_imx94_m33s = {
1533 .att = imx_rproc_att_imx94_m33s,
1534 .att_size = ARRAY_SIZE(imx_rproc_att_imx94_m33s),
1535 .ops = &imx_rproc_ops_sm_lmm,
1536 .cpuid = 8,
1537 .lmid = 1,
1538 .reset_vector_mask = GENMASK_U32(31, 16),
1539};
1540
1458static const struct imx_rproc_dcfg imx_rproc_cfg_imx95_m7 = {1541static const struct imx_rproc_dcfg imx_rproc_cfg_imx95_m7 = {
1459 .att = imx_rproc_att_imx95_m7,1542 .att = imx_rproc_att_imx95_m7,
1460 .att_size = ARRAY_SIZE(imx_rproc_att_imx95_m7),1543 .att_size = ARRAY_SIZE(imx_rproc_att_imx95_m7),
@@ -1462,6 +1545,7 @@ static const struct imx_rproc_dcfg imx_rproc_cfg_imx95_m7 = { · 1 unmodified line
1462 /* Must align with System Manager Firmware */1545 /* Must align with System Manager Firmware */
1463 .cpuid = 1, /* Use 1 as cpu id for M7 core */1546 .cpuid = 1, /* Use 1 as cpu id for M7 core */
1464 .lmid = 1, /* Use 1 as Logical Machine ID where M7 resides */1547 .lmid = 1, /* Use 1 as Logical Machine ID where M7 resides */
1548 .reset_vector_mask = GENMASK_U32(31, 16),
1465};1549};
1466 1550
1467static const struct of_device_id imx_rproc_of_match[] = {1551static const struct of_device_id imx_rproc_of_match[] = {
@@ -1478,6 +1562,9 @@ static const struct of_device_id imx_rproc_of_match[] = { · 10 unmodified lines
1478 { .compatible = "fsl,imx8qm-cm4", .data = &imx_rproc_cfg_imx8qm },1562 { .compatible = "fsl,imx8qm-cm4", .data = &imx_rproc_cfg_imx8qm },
1479 { .compatible = "fsl,imx8ulp-cm33", .data = &imx_rproc_cfg_imx8ulp },1563 { .compatible = "fsl,imx8ulp-cm33", .data = &imx_rproc_cfg_imx8ulp },
1480 { .compatible = "fsl,imx93-cm33", .data = &imx_rproc_cfg_imx93 },1564 { .compatible = "fsl,imx93-cm33", .data = &imx_rproc_cfg_imx93 },
1565 { .compatible = "fsl,imx94-cm70", .data = &imx_rproc_cfg_imx94_m70 },
1566 { .compatible = "fsl,imx94-cm71", .data = &imx_rproc_cfg_imx94_m71 },
1567 { .compatible = "fsl,imx94-cm33s", .data = &imx_rproc_cfg_imx94_m33s },
1481 { .compatible = "fsl,imx95-cm7", .data = &imx_rproc_cfg_imx95_m7 },1568 { .compatible = "fsl,imx95-cm7", .data = &imx_rproc_cfg_imx95_m7 },
1482 {},1569 {},
1483};1570};
drivers/remoteproc/imx_rproc.h+2−0
@@ -41,6 +41,8 @@ struct imx_rproc_dcfg { · 40 unmodified lines
41 /* For System Manager(SM) based SoCs */41 /* For System Manager(SM) based SoCs */
42 u32 cpuid; /* ID of the remote core */42 u32 cpuid; /* ID of the remote core */
43 u32 lmid; /* ID of the Logcial Machine */43 u32 lmid; /* ID of the Logcial Machine */
44 /* reset_vector = elf_entry_addr & reset_vector_mask */
45 u32 reset_vector_mask;
44};46};
45 47
46#endif /* _IMX_RPROC_H */48#endif /* _IMX_RPROC_H */
drivers/remoteproc/qcom_common.c+10−4
@@ -109,6 +109,7 @@ static int qcom_add_minidump_segments(struct rproc *rproc, struct minidump_subsy · 108 unmodified lines
109 struct minidump_region __iomem *ptr;109 struct minidump_region __iomem *ptr;
110 struct minidump_region region;110 struct minidump_region region;
111 int seg_cnt, i;111 int seg_cnt, i;
112 int ret = 0;
112 dma_addr_t da;113 dma_addr_t da;
113 size_t size;114 size_t size;
114 char *name;115 char *name;
@@ -129,17 +130,22 @@ static int qcom_add_minidump_segments(struct rproc *rproc, struct minidump_subsy · 14 unmodified lines
129 if (le32_to_cpu(region.valid) == MINIDUMP_REGION_VALID) {130 if (le32_to_cpu(region.valid) == MINIDUMP_REGION_VALID) {
130 name = kstrndup(region.name, MAX_REGION_NAME_LENGTH - 1, GFP_KERNEL);131 name = kstrndup(region.name, MAX_REGION_NAME_LENGTH - 1, GFP_KERNEL);
131 if (!name) {132 if (!name) {
132 iounmap(ptr);133 ret = -ENOMEM;
133 return -ENOMEM;134 break;
134 }135 }
135 da = le64_to_cpu(region.address);136 da = le64_to_cpu(region.address);
136 size = le64_to_cpu(region.size);137 size = le64_to_cpu(region.size);
137 rproc_coredump_add_custom_segment(rproc, da, size, rproc_dumpfn_t, name);138 ret = rproc_coredump_add_custom_segment(rproc, da, size, rproc_dumpfn_t,
139 name);
140 if (ret) {
141 kfree(name);
142 break;
143 }
138 }144 }
139 }145 }
140 146
141 iounmap(ptr);147 iounmap(ptr);
142 return 0;148 return ret;
143}149}
144 150
145void qcom_minidump(struct rproc *rproc, unsigned int minidump_id,151void qcom_minidump(struct rproc *rproc, unsigned int minidump_id,
drivers/remoteproc/qcom_q6v5_pas.c+48−3
@@ -92,9 +92,6 @@ struct qcom_pas { · 91 unmodified lines
92 const struct firmware *firmware;92 const struct firmware *firmware;
93 const struct firmware *dtb_firmware;93 const struct firmware *dtb_firmware;
94 94
95 struct completion start_done;
96 struct completion stop_done;
97
98 phys_addr_t mem_phys;95 phys_addr_t mem_phys;
99 phys_addr_t dtb_mem_phys;96 phys_addr_t dtb_mem_phys;
100 phys_addr_t mem_reloc;97 phys_addr_t mem_reloc;
@@ -1457,6 +1454,51 @@ static const struct qcom_pas_data sc7280_wpss_resource = { · 1356 unmodified lines
1457 .ssctl_id = 0x19,1454 .ssctl_id = 0x19,
1458};1455};
1459 1456
1457static const struct qcom_pas_data shikra_cdsp_resource = {
1458 .crash_reason_smem = 601,
1459 .firmware_name = "cdsp.mbn",
1460 .pas_id = 18,
1461 .minidump_id = 7,
1462 .auto_boot = true,
1463 .proxy_pd_names = (char *[]){
1464 "cx",
1465 NULL
1466 },
1467 .load_state = "cdsp",
1468 .ssr_name = "cdsp",
1469 .sysmon_name = "cdsp",
1470 .ssctl_id = 0x17,
1471 .smem_host_id = 5,
1472};
1473
1474static const struct qcom_pas_data shikra_lpaicp_resource = {
1475 .crash_reason_smem = 682,
1476 .firmware_name = "lpaicp.mbn",
1477 .dtb_firmware_name = "lpaicp_dtb.mbn",
1478 .pas_id = 0x56,
1479 .dtb_pas_id = 0x57,
1480 .minidump_id = 0,
1481 .auto_boot = true,
1482 .ssr_name = "lpaicp",
1483 .sysmon_name = "lpaicp",
1484};
1485
1486static const struct qcom_pas_data shikra_mpss_resource = {
1487 .crash_reason_smem = 421,
1488 .firmware_name = "qdsp6sw.mbn",
1489 .pas_id = 4,
1490 .minidump_id = 3,
1491 .auto_boot = false,
1492 .proxy_pd_names = (char *[]){
1493 "cx",
1494 NULL
1495 },
1496 .load_state = "modem",
1497 .ssr_name = "mpss",
1498 .sysmon_name = "modem",
1499 .ssctl_id = 0x12,
1500};
1501
1460static const struct qcom_pas_data sm8650_cdsp_resource = {1502static const struct qcom_pas_data sm8650_cdsp_resource = {
1461 .crash_reason_smem = 601,1503 .crash_reason_smem = 601,
1462 .firmware_name = "cdsp.mdt",1504 .firmware_name = "cdsp.mdt",
@@ -1571,6 +1613,9 @@ static const struct of_device_id qcom_pas_of_match[] = { · 108 unmodified lines
1571 { .compatible = "qcom,sdm845-slpi-pas", .data = &sdm845_slpi_resource_init },1613 { .compatible = "qcom,sdm845-slpi-pas", .data = &sdm845_slpi_resource_init },
1572 { .compatible = "qcom,sdx55-mpss-pas", .data = &sdx55_mpss_resource },1614 { .compatible = "qcom,sdx55-mpss-pas", .data = &sdx55_mpss_resource },
1573 { .compatible = "qcom,sdx75-mpss-pas", .data = &sm8650_mpss_resource },1615 { .compatible = "qcom,sdx75-mpss-pas", .data = &sm8650_mpss_resource },
1616 { .compatible = "qcom,shikra-cdsp-pas", .data = &shikra_cdsp_resource },
1617 { .compatible = "qcom,shikra-lpaicp-pas", .data = &shikra_lpaicp_resource },
1618 { .compatible = "qcom,shikra-mpss-pas", .data = &shikra_mpss_resource },
1574 { .compatible = "qcom,sm6115-adsp-pas", .data = &adsp_resource_init },1619 { .compatible = "qcom,sm6115-adsp-pas", .data = &adsp_resource_init },
1575 { .compatible = "qcom,sm6115-cdsp-pas", .data = &cdsp_resource_init },1620 { .compatible = "qcom,sm6115-cdsp-pas", .data = &cdsp_resource_init },
1576 { .compatible = "qcom,sm6115-mpss-pas", .data = &sc8180x_mpss_resource },1621 { .compatible = "qcom,sm6115-mpss-pas", .data = &sc8180x_mpss_resource },
drivers/remoteproc/qcom_q6v5_wcss.c+5−18
@@ -96,7 +96,6 @@ struct wcss_data { · 95 unmodified lines
96 unsigned int crash_reason_smem;96 unsigned int crash_reason_smem;
97 u32 version;97 u32 version;
98 bool aon_reset_required;98 bool aon_reset_required;
99 bool wcss_q6_reset_required;
100 const char *ssr_name;99 const char *ssr_name;
101 const char *sysmon_name;100 const char *sysmon_name;
102 int ssctl_id;101 int ssctl_id;
@@ -134,7 +133,6 @@ struct q6v5_wcss { · 31 unmodified lines
134 struct reset_control *wcss_aon_reset;133 struct reset_control *wcss_aon_reset;
135 struct reset_control *wcss_reset;134 struct reset_control *wcss_reset;
136 struct reset_control *wcss_q6_reset;135 struct reset_control *wcss_q6_reset;
137 struct reset_control *wcss_q6_bcr_reset;
138 136
139 struct qcom_q6v5 q6v5;137 struct qcom_q6v5 q6v5;
140 138
@@ -309,7 +307,7 @@ static int q6v5_wcss_qcs404_power_on(struct q6v5_wcss *wcss) · 168 unmodified lines
309 return ret;307 return ret;
310 308
311 /* Remove reset to the WCNSS QDSP6SS */309 /* Remove reset to the WCNSS QDSP6SS */
312 reset_control_deassert(wcss->wcss_q6_bcr_reset);310 reset_control_deassert(wcss->wcss_q6_reset);
313 311
314 /* Enable Q6SSTOP_AHBFABRIC_CBCR clock */312 /* Enable Q6SSTOP_AHBFABRIC_CBCR clock */
315 ret = clk_prepare_enable(wcss->ahbfabric_cbcr_clk);313 ret = clk_prepare_enable(wcss->ahbfabric_cbcr_clk);
@@ -803,19 +801,10 @@ static int q6v5_wcss_init_reset(struct q6v5_wcss *wcss, · 487 unmodified lines
803 return PTR_ERR(wcss->wcss_reset);801 return PTR_ERR(wcss->wcss_reset);
804 }802 }
805 803
806 if (desc->wcss_q6_reset_required) {804 wcss->wcss_q6_reset = devm_reset_control_get_exclusive(dev, "wcss_q6_reset");
807 wcss->wcss_q6_reset = devm_reset_control_get_exclusive(dev, "wcss_q6_reset");805 if (IS_ERR(wcss->wcss_q6_reset)) {
808 if (IS_ERR(wcss->wcss_q6_reset)) {806 dev_err(wcss->dev, "unable to acquire wcss_q6_reset\n");
809 dev_err(wcss->dev, "unable to acquire wcss_q6_reset\n");807 return PTR_ERR(wcss->wcss_q6_reset);
810 return PTR_ERR(wcss->wcss_q6_reset);
811 }
812 }
813
814 wcss->wcss_q6_bcr_reset = devm_reset_control_get_optional_exclusive(dev,
815 "wcss_q6_bcr_reset");
816 if (IS_ERR(wcss->wcss_q6_bcr_reset)) {
817 dev_err(wcss->dev, "unable to acquire wcss_q6_bcr_reset\n");
818 return PTR_ERR(wcss->wcss_q6_bcr_reset);
819 }808 }
820 809
821 return 0;810 return 0;
@@ -1062,7 +1051,6 @@ static const struct wcss_data wcss_ipq8074_res_init = { · 240 unmodified lines
1062 .firmware_name = "IPQ8074/q6_fw.mdt",1051 .firmware_name = "IPQ8074/q6_fw.mdt",
1063 .crash_reason_smem = WCSS_CRASH_REASON,1052 .crash_reason_smem = WCSS_CRASH_REASON,
1064 .aon_reset_required = true,1053 .aon_reset_required = true,
1065 .wcss_q6_reset_required = true,
1066 .ops = &q6v5_wcss_ipq8074_ops,1054 .ops = &q6v5_wcss_ipq8074_ops,
1067 .requires_force_stop = true,1055 .requires_force_stop = true,
1068};1056};
@@ -1072,7 +1060,6 @@ static const struct wcss_data wcss_qcs404_res_init = { · 3 unmodified lines
1072 .firmware_name = "wcnss.mdt",1060 .firmware_name = "wcnss.mdt",
1073 .version = WCSS_QCS404,1061 .version = WCSS_QCS404,
1074 .aon_reset_required = false,1062 .aon_reset_required = false,
1075 .wcss_q6_reset_required = false,
1076 .ssr_name = "mpss",1063 .ssr_name = "mpss",
1077 .sysmon_name = "wcnss",1064 .sysmon_name = "wcnss",
1078 .ssctl_id = 0x12,1065 .ssctl_id = 0x12,
drivers/remoteproc/remoteproc_core.c+38−43
@@ -1011,60 +1011,55 @@ static rproc_handle_resource_t rproc_loading_handlers[RSC_LAST] = { · 1010 unmodified lines
1011 [RSC_VDEV] = rproc_handle_vdev,1011 [RSC_VDEV] = rproc_handle_vdev,
1012};1012};
1013 1013
1014/* handle firmware resource entries before booting the remote processor */1014struct rproc_rsc_cb_data {
1015static int rproc_handle_resources(struct rproc *rproc,1015 struct rproc *rproc;
1016 rproc_handle_resource_t handlers[RSC_LAST])1016 rproc_handle_resource_t *handlers;
1017};
1018
1019static int rproc_handle_rsc_entry(u32 type, void *rsc, int offset,
1020 int avail, void *data)
1017{1021{
1022 struct rproc_rsc_cb_data *d = data;
1023 struct rproc *rproc = d->rproc;
1018 struct device *dev = &rproc->dev;1024 struct device *dev = &rproc->dev;
1019 rproc_handle_resource_t handler;1025 rproc_handle_resource_t handler;
1020 int ret = 0, i;1026 int ret;
1021
1022 if (!rproc->table_ptr)
1023 return 0;
1024 1027
1025 for (i = 0; i < rproc->table_ptr->num; i++) {1028 dev_dbg(dev, "rsc: type %d\n", type);
1026 int offset = rproc->table_ptr->offset[i];
1027 struct fw_rsc_hdr *hdr = (void *)rproc->table_ptr + offset;
1028 int avail = rproc->table_sz - offset - sizeof(*hdr);
1029 void *rsc = (void *)hdr + sizeof(*hdr);
1030 1029
1031 /* make sure table isn't truncated */1030 if (type >= RSC_VENDOR_START && type <= RSC_VENDOR_END) {
1032 if (avail < 0) {1031 ret = rproc_handle_rsc(rproc, type, rsc, offset, avail);
1033 dev_err(dev, "rsc table is truncated\n");1032 if (ret == RSC_HANDLED)
1034 return -EINVAL;1033 return 0;
1035 }1034 if (ret < 0)
1036 1035 return ret;
1037 dev_dbg(dev, "rsc: type %d\n", hdr->type);1036 dev_warn(dev, "unsupported vendor resource %d\n", type);
1037 return 0;
1038 }
1038 1039
1039 if (hdr->type >= RSC_VENDOR_START &&1040 if (type >= RSC_LAST) {
1040 hdr->type <= RSC_VENDOR_END) {1041 dev_warn(dev, "unsupported resource %d\n", type);
1041 ret = rproc_handle_rsc(rproc, hdr->type, rsc,1042 return 0;
1042 offset + sizeof(*hdr), avail);1043 }
1043 if (ret == RSC_HANDLED)
1044 continue;
1045 else if (ret < 0)
1046 break;
1047 1044
1048 dev_warn(dev, "unsupported vendor resource %d\n",1045 handler = d->handlers[type];
1049 hdr->type);1046 if (!handler)
1050 continue;1047 return 0;
1051 }
1052 1048
1053 if (hdr->type >= RSC_LAST) {1049 return handler(rproc, rsc, offset, avail);
1054 dev_warn(dev, "unsupported resource %d\n", hdr->type);1050}
1055 continue;
1056 }
1057 1051
1058 handler = handlers[hdr->type];1052/* handle firmware resource entries before booting the remote processor */
1059 if (!handler)1053static int rproc_handle_resources(struct rproc *rproc,
1060 continue;1054 rproc_handle_resource_t handlers[RSC_LAST])
1055{
1056 struct rproc_rsc_cb_data d = { .rproc = rproc, .handlers = handlers };
1061 1057
1062 ret = handler(rproc, rsc, offset + sizeof(*hdr), avail);1058 if (!rproc->table_ptr)
1063 if (ret)1059 return 0;
1064 break;
1065 }
1066 1060
1067 return ret;1061 return rsc_table_for_each_entry(rproc->table_ptr, rproc->table_sz,
1062 &rproc->dev, rproc_handle_rsc_entry, &d);
1068}1063}
1069 1064
1070static int rproc_prepare_subdevices(struct rproc *rproc)1065static int rproc_prepare_subdevices(struct rproc *rproc)
drivers/remoteproc/xlnx_r5_remoteproc.c+75−25
@@ -4,7 +4,6 @@ · 3 unmodified lines
4 *4 *
5 */5 */
6 6
7#include <dt-bindings/power/xlnx-zynqmp-power.h>
8#include <linux/dma-mapping.h>7#include <linux/dma-mapping.h>
9#include <linux/firmware/xlnx-zynqmp.h>8#include <linux/firmware/xlnx-zynqmp.h>
10#include <linux/kernel.h>9#include <linux/kernel.h>
@@ -19,6 +18,11 @@ · 8 unmodified lines
19 18
20#include "remoteproc_internal.h"19#include "remoteproc_internal.h"
21 20
21#define PD_R5_0_ATCM 15
22#define PD_R5_0_BTCM 16
23#define PD_R5_1_ATCM 17
24#define PD_R5_1_BTCM 18
25
22/* IPI buffer MAX length */26/* IPI buffer MAX length */
23#define IPI_BUF_LEN_MAX 32U27#define IPI_BUF_LEN_MAX 32U
24 28
@@ -899,17 +903,18 @@ static const struct rproc_ops zynqmp_r5_rproc_ops = { · 874 unmodified lines
899};903};
900 904
901/**905/**
902 * zynqmp_r5_add_rproc_core() - Add core data to framework.906 * zynqmp_r5_alloc_rproc_core() - alloc rproc core data structure
903 * Allocate and add struct rproc object for each r5f core907 * Allocate struct rproc object for each r5f core
904 * This is called for each individual r5f core908 * This is called for each individual r5f core
905 *909 *
906 * @cdev: Device node of each r5 core910 * @cdev: Device node of each r5 core
907 *911 *
908 * Return: zynqmp_r5_core object for success else error code pointer912 * Return: zynqmp_r5_core object for success else error code pointer
909 */913 */
910static struct zynqmp_r5_core *zynqmp_r5_add_rproc_core(struct device *cdev)914static struct zynqmp_r5_core *zynqmp_r5_alloc_rproc_core(struct device *cdev)
911{915{
912 struct zynqmp_r5_core *r5_core;916 struct zynqmp_r5_core *r5_core;
917 const char *fw_name = NULL;
913 struct rproc *r5_rproc;918 struct rproc *r5_rproc;
914 int ret;919 int ret;
915 920
@@ -918,10 +923,15 @@ static struct zynqmp_r5_core *zynqmp_r5_add_rproc_core(struct device *cdev) · 2 unmodified lines
918 if (ret)923 if (ret)
919 return ERR_PTR(ret);924 return ERR_PTR(ret);
920 925
926 ret = rproc_of_parse_firmware(cdev, 0, &fw_name);
927 if (ret < 0 && ret != -EINVAL)
928 return ERR_PTR(dev_err_probe(cdev, ret,
929 "failed to parse firmware-name\n"));
930
921 /* Allocate remoteproc instance */931 /* Allocate remoteproc instance */
922 r5_rproc = rproc_alloc(cdev, dev_name(cdev),932 r5_rproc = rproc_alloc(cdev, dev_name(cdev),
923 &zynqmp_r5_rproc_ops,933 &zynqmp_r5_rproc_ops,
924 NULL, sizeof(struct zynqmp_r5_core));934 fw_name, sizeof(struct zynqmp_r5_core));
925 if (!r5_rproc) {935 if (!r5_rproc) {
926 dev_err(cdev, "failed to allocate memory for rproc instance\n");936 dev_err(cdev, "failed to allocate memory for rproc instance\n");
927 return ERR_PTR(-ENOMEM);937 return ERR_PTR(-ENOMEM);
@@ -932,6 +942,11 @@ static struct zynqmp_r5_core *zynqmp_r5_add_rproc_core(struct device *cdev) · 4 unmodified lines
932 r5_rproc->recovery_disabled = true;942 r5_rproc->recovery_disabled = true;
933 r5_rproc->has_iommu = false;943 r5_rproc->has_iommu = false;
934 r5_rproc->auto_boot = false;944 r5_rproc->auto_boot = false;
945
946 /* attempt to boot automatically if the firmware-name is provided */
947 if (fw_name)
948 r5_rproc->auto_boot = true;
949
935 r5_core = r5_rproc->priv;950 r5_core = r5_rproc->priv;
936 r5_core->dev = cdev;951 r5_core->dev = cdev;
937 r5_core->np = dev_of_node(cdev);952 r5_core->np = dev_of_node(cdev);
@@ -941,23 +956,6 @@ static struct zynqmp_r5_core *zynqmp_r5_add_rproc_core(struct device *cdev) · 3 unmodified lines
941 goto free_rproc;956 goto free_rproc;
942 }957 }
943 958
944 /* Add R5 remoteproc core */
945 ret = rproc_add(r5_rproc);
946 if (ret) {
947 dev_err(cdev, "failed to add r5 remoteproc\n");
948 goto free_rproc;
949 }
950
951 /*
952 * If firmware is already available in the memory then move rproc state
953 * to DETACHED. Firmware can be preloaded via debugger or by any other
954 * agent (processors) in the system.
955 * If firmware isn't available in the memory and resource table isn't
956 * found, then rproc state remains OFFLINE.
957 */
958 if (!zynqmp_r5_get_rsc_table_va(r5_core))
959 r5_rproc->state = RPROC_DETACHED;
960
961 r5_core->rproc = r5_rproc;959 r5_core->rproc = r5_rproc;
962 return r5_core;960 return r5_core;
963 961
@@ -1210,6 +1208,7 @@ static int zynqmp_r5_core_init(struct zynqmp_r5_cluster *cluster, · 246 unmodified lines
1210{1208{
1211 struct device *dev = cluster->dev;1209 struct device *dev = cluster->dev;
1212 struct zynqmp_r5_core *r5_core;1210 struct zynqmp_r5_core *r5_core;
1211 u32 req, usage, status;
1213 int ret = -EINVAL, i;1212 int ret = -EINVAL, i;
1214 1213
1215 r5_core = cluster->r5_cores[0];1214 r5_core = cluster->r5_cores[0];
@@ -1255,6 +1254,42 @@ static int zynqmp_r5_core_init(struct zynqmp_r5_cluster *cluster, · 39 unmodified lines
1255 ret = zynqmp_r5_get_sram_banks(r5_core);1254 ret = zynqmp_r5_get_sram_banks(r5_core);
1256 if (ret)1255 if (ret)
1257 return ret;1256 return ret;
1257
1258 /*
1259 * It is possible that firmware is loaded into the memory, but
1260 * RPU (remote) is not running. In such case, RPU state will be
1261 * moved to RPROC_DETACHED wrongfully. To avoid it first make
1262 * sure RPU is power-on and out of reset before parsing for the
1263 * resource table.
1264 */
1265 ret = zynqmp_pm_get_rpu_node_status(r5_core->pm_domain_id,
1266 &status, &req, &usage);
1267 if (ret) {
1268 dev_warn(r5_core->dev,
1269 "failed to get rpu node status, err %d\n", ret);
1270 continue;
1271 }
1272
1273 /*
1274 * If RPU state is power on and out of reset i.e. running, then
1275 * assign RPROC_DETACHED state. If the RPU is not out of reset
1276 * then do not attempt to attach to the remote processor.
1277 */
1278 if (status == PM_NODE_RUNNING) {
1279 /*
1280 * Not all the firmware that is running on the remote
1281 * core is expected to have the resource table. The
1282 * firmware might not use RPMsg at all, and in that case
1283 * resource table becomes irrelevant. However, we still
1284 * need to make sure that running core is not reported
1285 * as offline. so do not decide remote core state based
1286 * on the resource table availability
1287 */
1288 if (zynqmp_r5_get_rsc_table_va(r5_core))
1289 dev_dbg(r5_core->dev, "rsc tbl not found\n");
1290 r5_core->rproc->state = RPROC_DETACHED;
1291 r5_core->rproc->auto_boot = true;
1292 }
1258 }1293 }
1259 1294
1260 return 0;1295 return 0;
@@ -1278,7 +1313,7 @@ static int zynqmp_r5_cluster_init(struct zynqmp_r5_cluster *cluster) · 17 unmodified lines
1278 enum rpu_oper_mode fw_reg_val;1313 enum rpu_oper_mode fw_reg_val;
1279 struct device **child_devs;1314 struct device **child_devs;
1280 enum rpu_tcm_comb tcm_mode;1315 enum rpu_tcm_comb tcm_mode;
1281 int core_count, ret, i;1316 int core_count, ret, i, j;
1282 struct mbox_info *ipi;1317 struct mbox_info *ipi;
1283 1318
1284 ret = of_property_read_u32(dev_node, "xlnx,cluster-mode", &cluster_mode);1319 ret = of_property_read_u32(dev_node, "xlnx,cluster-mode", &cluster_mode);
@@ -1364,7 +1399,7 @@ static int zynqmp_r5_cluster_init(struct zynqmp_r5_cluster *cluster) · 79 unmodified lines
1364 child_devs[i] = &child_pdev->dev;1399 child_devs[i] = &child_pdev->dev;
1365 1400
1366 /* create and add remoteproc instance of type struct rproc */1401 /* create and add remoteproc instance of type struct rproc */
1367 r5_cores[i] = zynqmp_r5_add_rproc_core(&child_pdev->dev);1402 r5_cores[i] = zynqmp_r5_alloc_rproc_core(&child_pdev->dev);
1368 if (IS_ERR(r5_cores[i])) {1403 if (IS_ERR(r5_cores[i])) {
1369 ret = PTR_ERR(r5_cores[i]);1404 ret = PTR_ERR(r5_cores[i]);
1370 r5_cores[i] = NULL;1405 r5_cores[i] = NULL;
@@ -1409,16 +1444,31 @@ static int zynqmp_r5_cluster_init(struct zynqmp_r5_cluster *cluster) · 38 unmodified lines
1409 goto release_r5_cores;1444 goto release_r5_cores;
1410 }1445 }
1411 1446
1447 for (j = 0; j < cluster->core_count; j++) {
1448 /* Add R5 remoteproc core */
1449 ret = rproc_add(r5_cores[j]->rproc);
1450 if (ret) {
1451 dev_err_probe(r5_cores[j]->dev, ret,
1452 "failed to add remoteproc\n");
1453 goto delete_r5_cores;
1454 }
1455 }
1456
1412 kfree(child_devs);1457 kfree(child_devs);
1413 return 0;1458 return 0;
1414 1459
1460delete_r5_cores:
1461 i = core_count - 1;
1462 /* delete previous added rproc */
1463 while (--j >= 0)
1464 rproc_del(r5_cores[j]->rproc);
1465
1415release_r5_cores:1466release_r5_cores:
1416 while (i >= 0) {1467 while (i >= 0) {
1417 put_device(child_devs[i]);1468 put_device(child_devs[i]);
1418 if (r5_cores[i]) {1469 if (r5_cores[i]) {
1419 zynqmp_r5_free_mbox(r5_cores[i]->ipi);1470 zynqmp_r5_free_mbox(r5_cores[i]->ipi);
1420 of_reserved_mem_device_release(r5_cores[i]->dev);1471 of_reserved_mem_device_release(r5_cores[i]->dev);
1421 rproc_del(r5_cores[i]->rproc);
1422 rproc_free(r5_cores[i]->rproc);1472 rproc_free(r5_cores[i]->rproc);
1423 }1473 }
1424 i--;1474 i--;
include/linux/firmware/xlnx-zynqmp.h+21−0
@@ -542,6 +542,18 @@ enum pm_gem_config_type { · 541 unmodified lines
542 GEM_CONFIG_FIXED = 2,542 GEM_CONFIG_FIXED = 2,
543};543};
544 544
545/**
546 * enum pm_node_status - Device node status provided by xilpm fw
547 * @PM_NODE_UNUSED: Device is not used
548 * @PM_NODE_RUNNING: Device is power-on and out of reset
549 * @PM_NODE_HALT: Device is power-on but in the reset state
550 */
551enum pm_node_status {
552 PM_NODE_UNUSED = 0,
553 PM_NODE_RUNNING = 1,
554 PM_NODE_HALT = 12,
555};
556
545/**557/**
546 * struct zynqmp_pm_query_data - PM query data558 * struct zynqmp_pm_query_data - PM query data
547 * @qid: query ID559 * @qid: query ID
@@ -630,6 +642,8 @@ int zynqmp_pm_set_rpu_mode(u32 node_id, enum rpu_oper_mode rpu_mode); · 82 unmodified lines
630int zynqmp_pm_set_tcm_config(u32 node_id, enum rpu_tcm_comb tcm_mode);642int zynqmp_pm_set_tcm_config(u32 node_id, enum rpu_tcm_comb tcm_mode);
631int zynqmp_pm_get_node_status(const u32 node, u32 *const status,643int zynqmp_pm_get_node_status(const u32 node, u32 *const status,
632 u32 *const requirements, u32 *const usage);644 u32 *const requirements, u32 *const usage);
645int zynqmp_pm_get_rpu_node_status(const u32 node, u32 *const status,
646 u32 *const requirements, u32 *const usage);
633int zynqmp_pm_set_sd_config(u32 node, enum pm_sd_config_type config, u32 value);647int zynqmp_pm_set_sd_config(u32 node, enum pm_sd_config_type config, u32 value);
634int zynqmp_pm_set_gem_config(u32 node, enum pm_gem_config_type config,648int zynqmp_pm_set_gem_config(u32 node, enum pm_gem_config_type config,
635 u32 value);649 u32 value);
@@ -939,6 +953,13 @@ static inline int zynqmp_pm_get_node_status(const u32 node, u32 *const status, · 303 unmodified lines
939 return -ENODEV;953 return -ENODEV;
940}954}
941 955
956static inline int zynqmp_pm_get_rpu_node_status(const u32 node, u32 *const status,
957 u32 *const requirements,
958 u32 *const usage)
959{
960 return -ENODEV;
961}
962
942static inline int zynqmp_pm_set_sd_config(u32 node,963static inline int zynqmp_pm_set_sd_config(u32 node,
943 enum pm_sd_config_type config,964 enum pm_sd_config_type config,
944 u32 value)965 u32 value)
include/linux/remoteproc.h+1−268
@@ -42,274 +42,7 @@ · 41 unmodified lines
42#include <linux/completion.h>42#include <linux/completion.h>
43#include <linux/idr.h>43#include <linux/idr.h>
44#include <linux/of.h>44#include <linux/of.h>
45 45#include <linux/rsc_table.h>
46/**
47 * struct resource_table - firmware resource table header
48 * @ver: version number
49 * @num: number of resource entries
50 * @reserved: reserved (must be zero)
51 * @offset: array of offsets pointing at the various resource entries
52 *
53 * A resource table is essentially a list of system resources required
54 * by the remote processor. It may also include configuration entries.
55 * If needed, the remote processor firmware should contain this table
56 * as a dedicated ".resource_table" ELF section.
57 *
58 * Some resources entries are mere announcements, where the host is informed
59 * of specific remoteproc configuration. Other entries require the host to
60 * do something (e.g. allocate a system resource). Sometimes a negotiation
61 * is expected, where the firmware requests a resource, and once allocated,
62 * the host should provide back its details (e.g. address of an allocated
63 * memory region).
64 *
65 * The header of the resource table, as expressed by this structure,
66 * contains a version number (should we need to change this format in the
67 * future), the number of available resource entries, and their offsets
68 * in the table.
69 *
70 * Immediately following this header are the resource entries themselves,
71 * each of which begins with a resource entry header (as described below).
72 */
73struct resource_table {
74 u32 ver;
75 u32 num;
76 u32 reserved[2];
77 u32 offset[];
78} __packed;
79
80/**
81 * struct fw_rsc_hdr - firmware resource entry header
82 * @type: resource type
83 * @data: resource data
84 *
85 * Every resource entry begins with a 'struct fw_rsc_hdr' header providing
86 * its @type. The content of the entry itself will immediately follow
87 * this header, and it should be parsed according to the resource type.
88 */
89struct fw_rsc_hdr {
90 u32 type;
91 u8 data[];
92} __packed;
93
94/**
95 * enum fw_resource_type - types of resource entries
96 *
97 * @RSC_CARVEOUT: request for allocation of a physically contiguous
98 * memory region.
99 * @RSC_DEVMEM: request to iommu_map a memory-based peripheral.
100 * @RSC_TRACE: announces the availability of a trace buffer into which
101 * the remote processor will be writing logs.
102 * @RSC_VDEV: declare support for a virtio device, and serve as its
103 * virtio header.
104 * @RSC_LAST: just keep this one at the end of standard resources
105 * @RSC_VENDOR_START: start of the vendor specific resource types range
106 * @RSC_VENDOR_END: end of the vendor specific resource types range
107 *
108 * For more details regarding a specific resource type, please see its
109 * dedicated structure below.
110 *
111 * Please note that these values are used as indices to the rproc_handle_rsc
112 * lookup table, so please keep them sane. Moreover, @RSC_LAST is used to
113 * check the validity of an index before the lookup table is accessed, so
114 * please update it as needed.
115 */
116enum fw_resource_type {
117 RSC_CARVEOUT = 0,
118 RSC_DEVMEM = 1,
119 RSC_TRACE = 2,
120 RSC_VDEV = 3,
121 RSC_LAST = 4,
122 RSC_VENDOR_START = 128,
123 RSC_VENDOR_END = 512,
124};
125
126#define FW_RSC_ADDR_ANY (-1)
127
128/**
129 * struct fw_rsc_carveout - physically contiguous memory request
130 * @da: device address
131 * @pa: physical address
132 * @len: length (in bytes)
133 * @flags: iommu protection flags
134 * @reserved: reserved (must be zero)
135 * @name: human-readable name of the requested memory region
136 *
137 * This resource entry requests the host to allocate a physically contiguous
138 * memory region.
139 *
140 * These request entries should precede other firmware resource entries,
141 * as other entries might request placing other data objects inside
142 * these memory regions (e.g. data/code segments, trace resource entries, ...).
143 *
144 * Allocating memory this way helps utilizing the reserved physical memory
145 * (e.g. CMA) more efficiently, and also minimizes the number of TLB entries
146 * needed to map it (in case @rproc is using an IOMMU). Reducing the TLB
147 * pressure is important; it may have a substantial impact on performance.
148 *
149 * If the firmware is compiled with static addresses, then @da should specify
150 * the expected device address of this memory region. If @da is set to
151 * FW_RSC_ADDR_ANY, then the host will dynamically allocate it, and then
152 * overwrite @da with the dynamically allocated address.
153 *
154 * We will always use @da to negotiate the device addresses, even if it
155 * isn't using an iommu. In that case, though, it will obviously contain
156 * physical addresses.
157 *
158 * Some remote processors needs to know the allocated physical address
159 * even if they do use an iommu. This is needed, e.g., if they control
160 * hardware accelerators which access the physical memory directly (this
161 * is the case with OMAP4 for instance). In that case, the host will
162 * overwrite @pa with the dynamically allocated physical address.
163 * Generally we don't want to expose physical addresses if we don't have to
164 * (remote processors are generally _not_ trusted), so we might want to
165 * change this to happen _only_ when explicitly required by the hardware.
166 *
167 * @flags is used to provide IOMMU protection flags, and @name should
168 * (optionally) contain a human readable name of this carveout region
169 * (mainly for debugging purposes).
170 */
171struct fw_rsc_carveout {
172 u32 da;
173 u32 pa;
174 u32 len;
175 u32 flags;
176 u32 reserved;
177 u8 name[32];
178} __packed;
179
180/**
181 * struct fw_rsc_devmem - iommu mapping request
182 * @da: device address
183 * @pa: physical address
184 * @len: length (in bytes)
185 * @flags: iommu protection flags
186 * @reserved: reserved (must be zero)
187 * @name: human-readable name of the requested region to be mapped
188 *
189 * This resource entry requests the host to iommu map a physically contiguous
190 * memory region. This is needed in case the remote processor requires
191 * access to certain memory-based peripherals; _never_ use it to access
192 * regular memory.
193 *
194 * This is obviously only needed if the remote processor is accessing memory
195 * via an iommu.
196 *
197 * @da should specify the required device address, @pa should specify
198 * the physical address we want to map, @len should specify the size of
199 * the mapping and @flags is the IOMMU protection flags. As always, @name may
200 * (optionally) contain a human readable name of this mapping (mainly for
201 * debugging purposes).
202 *
203 * Note: at this point we just "trust" those devmem entries to contain valid
204 * physical addresses, but this isn't safe and will be changed: eventually we
205 * want remoteproc implementations to provide us ranges of physical addresses
206 * the firmware is allowed to request, and not allow firmwares to request
207 * access to physical addresses that are outside those ranges.
208 */
209struct fw_rsc_devmem {
210 u32 da;
211 u32 pa;
212 u32 len;
213 u32 flags;
214 u32 reserved;
215 u8 name[32];
216} __packed;
217
218/**
219 * struct fw_rsc_trace - trace buffer declaration
220 * @da: device address
221 * @len: length (in bytes)
222 * @reserved: reserved (must be zero)
223 * @name: human-readable name of the trace buffer
224 *
225 * This resource entry provides the host information about a trace buffer
226 * into which the remote processor will write log messages.
227 *
228 * @da specifies the device address of the buffer, @len specifies
229 * its size, and @name may contain a human readable name of the trace buffer.
230 *
231 * After booting the remote processor, the trace buffers are exposed to the
232 * user via debugfs entries (called trace0, trace1, etc..).
233 */
234struct fw_rsc_trace {
235 u32 da;
236 u32 len;
237 u32 reserved;
238 u8 name[32];
239} __packed;
240
241/**
242 * struct fw_rsc_vdev_vring - vring descriptor entry
243 * @da: device address
244 * @align: the alignment between the consumer and producer parts of the vring
245 * @num: num of buffers supported by this vring (must be power of two)
246 * @notifyid: a unique rproc-wide notify index for this vring. This notify
247 * index is used when kicking a remote processor, to let it know that this
248 * vring is triggered.
249 * @pa: physical address
250 *
251 * This descriptor is not a resource entry by itself; it is part of the
252 * vdev resource type (see below).
253 *
254 * Note that @da should either contain the device address where
255 * the remote processor is expecting the vring, or indicate that
256 * dynamically allocation of the vring's device address is supported.
257 */
258struct fw_rsc_vdev_vring {
259 u32 da;
260 u32 align;
261 u32 num;
262 u32 notifyid;
263 u32 pa;
264} __packed;
265
266/**
267 * struct fw_rsc_vdev - virtio device header
268 * @id: virtio device id (as in virtio_ids.h)
269 * @notifyid: a unique rproc-wide notify index for this vdev. This notify
270 * index is used when kicking a remote processor, to let it know that the
271 * status/features of this vdev have changes.
272 * @dfeatures: specifies the virtio device features supported by the firmware
273 * @gfeatures: a place holder used by the host to write back the
274 * negotiated features that are supported by both sides.
275 * @config_len: the size of the virtio config space of this vdev. The config
276 * space lies in the resource table immediate after this vdev header.
277 * @status: a place holder where the host will indicate its virtio progress.
278 * @num_of_vrings: indicates how many vrings are described in this vdev header
279 * @reserved: reserved (must be zero)
280 * @vring: an array of @num_of_vrings entries of 'struct fw_rsc_vdev_vring'.
281 *
282 * This resource is a virtio device header: it provides information about
283 * the vdev, and is then used by the host and its peer remote processors
284 * to negotiate and share certain virtio properties.
285 *
286 * By providing this resource entry, the firmware essentially asks remoteproc
287 * to statically allocate a vdev upon registration of the rproc (dynamic vdev
288 * allocation is not yet supported).
289 *
290 * Note:
291 * 1. unlike virtualization systems, the term 'host' here means
292 * the Linux side which is running remoteproc to control the remote
293 * processors. We use the name 'gfeatures' to comply with virtio's terms,
294 * though there isn't really any virtualized guest OS here: it's the host
295 * which is responsible for negotiating the final features.
296 * Yeah, it's a bit confusing.
297 *
298 * 2. immediately following this structure is the virtio config space for
299 * this vdev (which is specific to the vdev; for more info, read the virtio
300 * spec). The size of the config space is specified by @config_len.
301 */
302struct fw_rsc_vdev {
303 u32 id;
304 u32 notifyid;
305 u32 dfeatures;
306 u32 gfeatures;
307 u32 config_len;
308 u8 status;
309 u8 num_of_vrings;
310 u8 reserved[2];
311 struct fw_rsc_vdev_vring vring[];
312} __packed;
313 46
314struct rproc;47struct rproc;
315 48
include/linux/rsc_table.h+359−0
@@ -0,0 +1,359 @@
1/*
2 * Resource table and its types data structure
3 *
4 * Copyright(c) 2011 Texas Instruments, Inc.
5 * Copyright(c) 2011 Google, Inc.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * * Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * * Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in
16 * the documentation and/or other materials provided with the
17 * distribution.
18 * * Neither the name Texas Instruments nor the names of its
19 * contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 */
34
35#ifndef RSC_TABLE_H
36#define RSC_TABLE_H
37
38/**
39 * struct resource_table - firmware resource table header
40 * @ver: version number
41 * @num: number of resource entries
42 * @reserved: reserved (must be zero)
43 * @offset: array of offsets pointing at the various resource entries
44 *
45 * A resource table is essentially a list of system resources required
46 * by the remote processor. It may also include configuration entries.
47 * If needed, the remote processor firmware should contain this table
48 * as a dedicated ".resource_table" ELF section.
49 *
50 * Some resources entries are mere announcements, where the host is informed
51 * of specific remoteproc configuration. Other entries require the host to
52 * do something (e.g. allocate a system resource). Sometimes a negotiation
53 * is expected, where the firmware requests a resource, and once allocated,
54 * the host should provide back its details (e.g. address of an allocated
55 * memory region).
56 *
57 * The header of the resource table, as expressed by this structure,
58 * contains a version number (should we need to change this format in the
59 * future), the number of available resource entries, and their offsets
60 * in the table.
61 *
62 * Immediately following this header are the resource entries themselves,
63 * each of which begins with a resource entry header (as described below).
64 */
65struct resource_table {
66 u32 ver;
67 u32 num;
68 u32 reserved[2];
69 u32 offset[];
70} __packed;
71
72/**
73 * struct fw_rsc_hdr - firmware resource entry header
74 * @type: resource type
75 * @data: resource data
76 *
77 * Every resource entry begins with a 'struct fw_rsc_hdr' header providing
78 * its @type. The content of the entry itself will immediately follow
79 * this header, and it should be parsed according to the resource type.
80 */
81struct fw_rsc_hdr {
82 u32 type;
83 u8 data[];
84} __packed;
85
86/**
87 * enum fw_resource_type - types of resource entries
88 *
89 * @RSC_CARVEOUT: request for allocation of a physically contiguous
90 * memory region.
91 * @RSC_DEVMEM: request to iommu_map a memory-based peripheral.
92 * @RSC_TRACE: announces the availability of a trace buffer into which
93 * the remote processor will be writing logs.
94 * @RSC_VDEV: declare support for a virtio device, and serve as its
95 * virtio header.
96 * @RSC_LAST: just keep this one at the end of standard resources
97 * @RSC_VENDOR_START: start of the vendor specific resource types range
98 * @RSC_VENDOR_END: end of the vendor specific resource types range
99 *
100 * For more details regarding a specific resource type, please see its
101 * dedicated structure below.
102 *
103 * Please note that these values are used as indices to the rproc_handle_rsc
104 * lookup table, so please keep them sane. Moreover, @RSC_LAST is used to
105 * check the validity of an index before the lookup table is accessed, so
106 * please update it as needed.
107 */
108enum fw_resource_type {
109 RSC_CARVEOUT = 0,
110 RSC_DEVMEM = 1,
111 RSC_TRACE = 2,
112 RSC_VDEV = 3,
113 RSC_LAST = 4,
114 RSC_VENDOR_START = 128,
115 RSC_VENDOR_END = 512,
116};
117
118#define FW_RSC_ADDR_ANY (-1)
119
120/**
121 * struct fw_rsc_carveout - physically contiguous memory request
122 * @da: device address
123 * @pa: physical address
124 * @len: length (in bytes)
125 * @flags: iommu protection flags
126 * @reserved: reserved (must be zero)
127 * @name: human-readable name of the requested memory region
128 *
129 * This resource entry requests the host to allocate a physically contiguous
130 * memory region.
131 *
132 * These request entries should precede other firmware resource entries,
133 * as other entries might request placing other data objects inside
134 * these memory regions (e.g. data/code segments, trace resource entries, ...).
135 *
136 * Allocating memory this way helps utilizing the reserved physical memory
137 * (e.g. CMA) more efficiently, and also minimizes the number of TLB entries
138 * needed to map it (in case @rproc is using an IOMMU). Reducing the TLB
139 * pressure is important; it may have a substantial impact on performance.
140 *
141 * If the firmware is compiled with static addresses, then @da should specify
142 * the expected device address of this memory region. If @da is set to
143 * FW_RSC_ADDR_ANY, then the host will dynamically allocate it, and then
144 * overwrite @da with the dynamically allocated address.
145 *
146 * We will always use @da to negotiate the device addresses, even if it
147 * isn't using an iommu. In that case, though, it will obviously contain
148 * physical addresses.
149 *
150 * Some remote processors needs to know the allocated physical address
151 * even if they do use an iommu. This is needed, e.g., if they control
152 * hardware accelerators which access the physical memory directly (this
153 * is the case with OMAP4 for instance). In that case, the host will
154 * overwrite @pa with the dynamically allocated physical address.
155 * Generally we don't want to expose physical addresses if we don't have to
156 * (remote processors are generally _not_ trusted), so we might want to
157 * change this to happen _only_ when explicitly required by the hardware.
158 *
159 * @flags is used to provide IOMMU protection flags, and @name should
160 * (optionally) contain a human readable name of this carveout region
161 * (mainly for debugging purposes).
162 */
163struct fw_rsc_carveout {
164 u32 da;
165 u32 pa;
166 u32 len;
167 u32 flags;
168 u32 reserved;
169 u8 name[32];
170} __packed;
171
172/**
173 * struct fw_rsc_devmem - iommu mapping request
174 * @da: device address
175 * @pa: physical address
176 * @len: length (in bytes)
177 * @flags: iommu protection flags
178 * @reserved: reserved (must be zero)
179 * @name: human-readable name of the requested region to be mapped
180 *
181 * This resource entry requests the host to iommu map a physically contiguous
182 * memory region. This is needed in case the remote processor requires
183 * access to certain memory-based peripherals; _never_ use it to access
184 * regular memory.
185 *
186 * This is obviously only needed if the remote processor is accessing memory
187 * via an iommu.
188 *
189 * @da should specify the required device address, @pa should specify
190 * the physical address we want to map, @len should specify the size of
191 * the mapping and @flags is the IOMMU protection flags. As always, @name may
192 * (optionally) contain a human readable name of this mapping (mainly for
193 * debugging purposes).
194 *
195 * Note: at this point we just "trust" those devmem entries to contain valid
196 * physical addresses, but this isn't safe and will be changed: eventually we
197 * want remoteproc implementations to provide us ranges of physical addresses
198 * the firmware is allowed to request, and not allow firmwares to request
199 * access to physical addresses that are outside those ranges.
200 */
201struct fw_rsc_devmem {
202 u32 da;
203 u32 pa;
204 u32 len;
205 u32 flags;
206 u32 reserved;
207 u8 name[32];
208} __packed;
209
210/**
211 * struct fw_rsc_trace - trace buffer declaration
212 * @da: device address
213 * @len: length (in bytes)
214 * @reserved: reserved (must be zero)
215 * @name: human-readable name of the trace buffer
216 *
217 * This resource entry provides the host information about a trace buffer
218 * into which the remote processor will write log messages.
219 *
220 * @da specifies the device address of the buffer, @len specifies
221 * its size, and @name may contain a human readable name of the trace buffer.
222 *
223 * After booting the remote processor, the trace buffers are exposed to the
224 * user via debugfs entries (called trace0, trace1, etc..).
225 */
226struct fw_rsc_trace {
227 u32 da;
228 u32 len;
229 u32 reserved;
230 u8 name[32];
231} __packed;
232
233/**
234 * struct fw_rsc_vdev_vring - vring descriptor entry
235 * @da: device address
236 * @align: the alignment between the consumer and producer parts of the vring
237 * @num: num of buffers supported by this vring (must be power of two)
238 * @notifyid: a unique rproc-wide notify index for this vring. This notify
239 * index is used when kicking a remote processor, to let it know that this
240 * vring is triggered.
241 * @pa: physical address
242 *
243 * This descriptor is not a resource entry by itself; it is part of the
244 * vdev resource type (see below).
245 *
246 * Note that @da should either contain the device address where
247 * the remote processor is expecting the vring, or indicate that
248 * dynamically allocation of the vring's device address is supported.
249 */
250struct fw_rsc_vdev_vring {
251 u32 da;
252 u32 align;
253 u32 num;
254 u32 notifyid;
255 u32 pa;
256} __packed;
257
258/**
259 * struct fw_rsc_vdev - virtio device header
260 * @id: virtio device id (as in virtio_ids.h)
261 * @notifyid: a unique rproc-wide notify index for this vdev. This notify
262 * index is used when kicking a remote processor, to let it know that the
263 * status/features of this vdev have changes.
264 * @dfeatures: specifies the virtio device features supported by the firmware
265 * @gfeatures: a place holder used by the host to write back the
266 * negotiated features that are supported by both sides.
267 * @config_len: the size of the virtio config space of this vdev. The config
268 * space lies in the resource table immediate after this vdev header.
269 * @status: a place holder where the host will indicate its virtio progress.
270 * @num_of_vrings: indicates how many vrings are described in this vdev header
271 * @reserved: reserved (must be zero)
272 * @vring: an array of @num_of_vrings entries of 'struct fw_rsc_vdev_vring'.
273 *
274 * This resource is a virtio device header: it provides information about
275 * the vdev, and is then used by the host and its peer remote processors
276 * to negotiate and share certain virtio properties.
277 *
278 * By providing this resource entry, the firmware essentially asks remoteproc
279 * to statically allocate a vdev upon registration of the rproc (dynamic vdev
280 * allocation is not yet supported).
281 *
282 * Note:
283 * 1. unlike virtualization systems, the term 'host' here means
284 * the Linux side which is running remoteproc to control the remote
285 * processors. We use the name 'gfeatures' to comply with virtio's terms,
286 * though there isn't really any virtualized guest OS here: it's the host
287 * which is responsible for negotiating the final features.
288 * Yeah, it's a bit confusing.
289 *
290 * 2. immediately following this structure is the virtio config space for
291 * this vdev (which is specific to the vdev; for more info, read the virtio
292 * spec). The size of the config space is specified by @config_len.
293 */
294struct fw_rsc_vdev {
295 u32 id;
296 u32 notifyid;
297 u32 dfeatures;
298 u32 gfeatures;
299 u32 config_len;
300 u8 status;
301 u8 num_of_vrings;
302 u8 reserved[2];
303 struct fw_rsc_vdev_vring vring[];
304} __packed;
305
306/**
307 * rsc_table_for_each_entry() - iterate over all entries in a resource table
308 * @table: pointer to the resource table
309 * @table_sz: total size of the table buffer in bytes
310 * @dev: device used for error logging
311 * @cb: callback invoked for each entry:
312 * @type - value from enum fw_resource_type
313 * @rsc - pointer to the entry payload (past struct fw_rsc_hdr)
314 * @offset - byte offset of the payload within the table; callers
315 * that write back into the table (e.g. to record a
316 * dynamically allocated address) use this to locate the
317 * entry for later update
318 * @avail - bytes available in the payload
319 * @data - caller-supplied private pointer
320 * Return 0 to continue iteration, non-zero to stop.
321 * @data: private pointer forwarded to @cb on every call
322 *
323 * Iterates over every resource entry in @table, performing the standard
324 * truncation check, and invokes @cb for each one. Iteration stops on the
325 * first non-zero return from @cb or on a malformed table.
326 *
327 * Returns 0 after a complete iteration, -EINVAL if the table is truncated,
328 * or the first non-zero value returned by @cb.
329 */
330static inline int rsc_table_for_each_entry(struct resource_table *table,
331 size_t table_sz,
332 struct device *dev,
333 int (*cb)(u32 type, void *rsc,
334 int offset, int avail,
335 void *data),
336 void *data) {
337 int i, ret;
338
339 for (i = 0; i < table->num; i++) {
340 int offset = table->offset[i];
341 struct fw_rsc_hdr *hdr = (void *)table + offset;
342 int avail = table_sz - offset - sizeof(*hdr);
343 int rsc_offset = offset + sizeof(*hdr);
344 void *rsc = (void *)hdr + sizeof(*hdr);
345
346 if (avail < 0) {
347 dev_err(dev, "rsc table is truncated\n");
348 return -EINVAL;
349 }
350
351 ret = cb(hdr->type, rsc, rsc_offset, avail, data);
352 if (ret)
353 return ret;
354 }
355
356 return 0;
357}
358
359#endif /* RSC_TABLE_H */

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t