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-v7.0' of git://git.kernel.org/pub/scm/linux/kernel/git/remoteproc/linux

Pull remoteproc updates from Bjorn Andersson:

- Fix a memory remapping issue and make a few life-cycle improvements
in the i.MX HiFi remoteproc driver

- Add support the System Manager CPU and LMM APIs and use this to
support i.MX95

- Rework the handling of the Mediatek SCP clock to avoid a potential
circular deadlock in the clock providers

- Refactor the Qualcomm secure-world helpers and add support in the
Qualcomm PAS remoteproc driver for reading a resource-table from
secure world. Use this to configure the IOMMU on newer targets where
Linux runs in EL2

* tag 'rproc-v7.0' of git://git.kernel.org/pub/scm/linux/kernel/git/remoteproc/linux:
remoteproc: imx_rproc: Fix invalid loaded resource table detection
remoteproc: mediatek: Break lock dependency to `prepare_lock`
remoteproc: imx_rproc: Add support for i.MX95
remoteproc: imx_rproc: Add support for System Manager CPU API
remoteproc: imx_rproc: Add support for System Manager LMM API
remoteproc: imx_rproc: Introduce prepare ops for imx_rproc_dcfg
remoteproc: imx_rproc: Add runtime ops copy to support dynamic behavior
dt-bindings: remoteproc: fsl,imx-rproc: Add support for i.MX95
dt-bindings: remoteproc: Add HSM M4F core on TI K3 SoCs
remoteproc: xlnx_r5: Simplify with scoped for each OF child loop
remoteproc: mtk_scp: Simplify with scoped for each OF child loop
remoteproc: imx_dsp_rproc: Only reset carveout memory at RPROC_OFFLINE state
dt-bindings: remoteproc: qcom,sm8550-pas: Drop SM8750 ADSP from if-branch
dt-bindings: remoteproc: qcom,adsp: Allow cx-supply on qcom,sdm845-slpi-pas
remoteproc: imx_dsp_rproc: Fix multiple start/stop operations
remoteproc: imx_rproc: Use strstarts for "rsc-table" check
remoteproc: imx_dsp_rproc: Wait for suspend ACK only if WAIT_FW_CONFIRMATION is set
remoteproc: imx_dsp_rproc: Rename macro to reflect multiple contexts
remoteproc: imx_dsp_rproc: Skip RP_MBOX_SUSPEND_SYSTEM when mailbox TX channel is uninitialized
dt-bindings: remoteproc: Fix dead link to Keystone DSP GPIO binding

+424 -74
+1
Documentation/devicetree/bindings/remoteproc/fsl,imx-rproc.yaml
··· 28 28 - fsl,imx8qxp-cm4 29 29 - fsl,imx8ulp-cm33 30 30 - fsl,imx93-cm33 31 + - fsl,imx95-cm7 31 32 32 33 clocks: 33 34 maxItems: 1
+5
Documentation/devicetree/bindings/remoteproc/qcom,adsp.yaml
··· 32 32 reg: 33 33 maxItems: 1 34 34 35 + cx-supply: true 36 + 35 37 px-supply: 36 38 description: Phandle to the PX regulator 37 39 ··· 161 159 items: 162 160 - const: lcx 163 161 - const: lmx 162 + else: 163 + properties: 164 + cx-supply: false 164 165 165 166 - if: 166 167 properties:
-1
Documentation/devicetree/bindings/remoteproc/qcom,sm8550-pas.yaml
··· 187 187 enum: 188 188 - qcom,sm8550-adsp-pas 189 189 - qcom,sm8650-adsp-pas 190 - - qcom,sm8750-adsp-pas 191 190 - qcom,x1e80100-adsp-pas 192 191 then: 193 192 properties:
+72
Documentation/devicetree/bindings/remoteproc/ti,hsm-m4fss.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/ti,hsm-m4fss.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: TI K3 HSM M4F processor subsystems 8 + 9 + maintainers: 10 + - Beleswar Padhi <b-padhi@ti.com> 11 + 12 + description: | 13 + Some K3 family SoCs have a HSM (High Security Module) M4F core in the 14 + Wakeup Voltage Domain which could be used to run secure services like 15 + Authentication. Some of those are J721S2, J784S4, J722S, AM62X. 16 + 17 + $ref: /schemas/arm/keystone/ti,k3-sci-common.yaml# 18 + 19 + properties: 20 + compatible: 21 + enum: 22 + - ti,hsm-m4fss 23 + 24 + reg: 25 + items: 26 + - description: SRAM0_0 internal memory region 27 + - description: SRAM0_1 internal memory region 28 + - description: SRAM1 internal memory region 29 + 30 + reg-names: 31 + items: 32 + - const: sram0_0 33 + - const: sram0_1 34 + - const: sram1 35 + 36 + resets: 37 + maxItems: 1 38 + 39 + firmware-name: 40 + maxItems: 1 41 + 42 + required: 43 + - compatible 44 + - reg 45 + - reg-names 46 + - resets 47 + - firmware-name 48 + - ti,sci 49 + - ti,sci-dev-id 50 + - ti,sci-proc-ids 51 + 52 + unevaluatedProperties: false 53 + 54 + examples: 55 + - | 56 + soc { 57 + #address-cells = <2>; 58 + #size-cells = <2>; 59 + 60 + remoteproc@43c00000 { 61 + compatible = "ti,hsm-m4fss"; 62 + reg = <0x00 0x43c00000 0x00 0x20000>, 63 + <0x00 0x43c20000 0x00 0x10000>, 64 + <0x00 0x43c30000 0x00 0x10000>; 65 + reg-names = "sram0_0", "sram0_1", "sram1"; 66 + resets = <&k3_reset 225 1>; 67 + firmware-name = "hsm.bin"; 68 + ti,sci = <&sms>; 69 + ti,sci-dev-id = <225>; 70 + ti,sci-proc-ids = <0x80 0xff>; 71 + }; 72 + };
+1 -1
Documentation/devicetree/bindings/remoteproc/ti,keystone-rproc.txt
··· 66 66 - kick-gpios: Should specify the gpio device needed for the virtio IPC 67 67 stack. This will be used to interrupt the remote processor. 68 68 The gpio device to be used is as per the bindings in, 69 - Documentation/devicetree/bindings/gpio/gpio-dsp-keystone.txt 69 + Documentation/devicetree/bindings/gpio/ti,keystone-dsp-gpio.yaml 70 70 71 71 SoC-specific Required properties: 72 72 ---------------------------------
+2
drivers/remoteproc/Kconfig
··· 27 27 tristate "i.MX remoteproc support" 28 28 depends on ARCH_MXC 29 29 depends on HAVE_ARM_SMCCC 30 + depends on IMX_SCMI_CPU_DRV || !IMX_SCMI_CPU_DRV 31 + depends on IMX_SCMI_LMM_DRV || !IMX_SCMI_LMM_DRV 30 32 select MAILBOX 31 33 help 32 34 Say y here to support iMX's remote processors via the remote
+64 -31
drivers/remoteproc/imx_dsp_rproc.c
··· 38 38 39 39 /* Flag indicating that the remote is up and running */ 40 40 #define REMOTE_IS_READY BIT(0) 41 - /* Flag indicating that the host should wait for a firmware-ready response */ 42 - #define WAIT_FW_READY BIT(1) 41 + /* Flag indicating that the host should wait for a firmware-confirmation response */ 42 + #define WAIT_FW_CONFIRMATION BIT(1) 43 43 #define REMOTE_READY_WAIT_MAX_RETRIES 500 44 44 45 45 /* 46 46 * This flag is set in the DSP resource table's features field to indicate 47 - * that the firmware requires the host NOT to wait for a FW_READY response. 47 + * that the firmware requires the host NOT to wait for a FW_CONFIRMATION response. 48 48 */ 49 - #define FEATURE_DONT_WAIT_FW_READY BIT(0) 49 + #define FEATURE_SKIP_FW_CONFIRMATION BIT(0) 50 50 51 51 /* att flags */ 52 52 /* DSP own area */ ··· 287 287 * @avail: available space in the resource table 288 288 * 289 289 * Parse the DSP-specific resource entry and update flags accordingly. 290 - * If the WAIT_FW_READY feature is set, the host must wait for the firmware 290 + * If the WAIT_FW_CONFIRMATION feature is set, the host must wait for the firmware 291 291 * to signal readiness before proceeding with execution. 292 292 * 293 293 * Return: RSC_HANDLED if processed successfully, RSC_IGNORED otherwise. ··· 322 322 323 323 /* 324 324 * For now, in struct fw_rsc_imx_dsp, version 0, 325 - * only FEATURE_DONT_WAIT_FW_READY is valid. 325 + * only FEATURE_SKIP_FW_CONFIRMATION is valid. 326 326 * 327 327 * When adding new features, please upgrade version. 328 328 */ ··· 332 332 return RSC_IGNORED; 333 333 } 334 334 335 - if (imx_dsp_rsc->features & FEATURE_DONT_WAIT_FW_READY) 336 - priv->flags &= ~WAIT_FW_READY; 335 + if (imx_dsp_rsc->features & FEATURE_SKIP_FW_CONFIRMATION) 336 + priv->flags &= ~WAIT_FW_CONFIRMATION; 337 337 338 338 return RSC_HANDLED; 339 339 } ··· 385 385 return ret; 386 386 } 387 387 388 - if (priv->flags & WAIT_FW_READY) 388 + if (priv->flags & WAIT_FW_CONFIRMATION) 389 389 return imx_dsp_rproc_ready(rproc); 390 390 391 391 return 0; ··· 644 644 mbox_free_channel(priv->rxdb_ch); 645 645 } 646 646 647 + static int imx_dsp_rproc_mem_alloc(struct rproc *rproc, 648 + struct rproc_mem_entry *mem) 649 + { 650 + struct device *dev = rproc->dev.parent; 651 + void *va; 652 + 653 + va = ioremap_wc(mem->dma, mem->len); 654 + if (!va) { 655 + dev_err(dev, "Unable to map memory region: %pa+%zx\n", 656 + &mem->dma, mem->len); 657 + return -ENOMEM; 658 + } 659 + 660 + mem->va = va; 661 + 662 + return 0; 663 + } 664 + 665 + static int imx_dsp_rproc_mem_release(struct rproc *rproc, 666 + struct rproc_mem_entry *mem) 667 + { 668 + iounmap(mem->va); 669 + 670 + return 0; 671 + } 672 + 647 673 /** 648 674 * imx_dsp_rproc_add_carveout() - request mailbox channels 649 675 * @priv: private data pointer ··· 685 659 struct device *dev = rproc->dev.parent; 686 660 struct device_node *np = dev->of_node; 687 661 struct rproc_mem_entry *mem; 688 - void __iomem *cpu_addr; 689 662 int a, i = 0; 690 663 u64 da; 691 664 ··· 698 673 if (imx_dsp_rproc_sys_to_da(priv, att->sa, att->size, &da)) 699 674 return -EINVAL; 700 675 701 - cpu_addr = devm_ioremap_wc(dev, att->sa, att->size); 702 - if (!cpu_addr) { 703 - dev_err(dev, "failed to map memory %p\n", &att->sa); 704 - return -ENOMEM; 705 - } 706 - 707 676 /* Register memory region */ 708 - mem = rproc_mem_entry_init(dev, (void __force *)cpu_addr, (dma_addr_t)att->sa, 709 - att->size, da, NULL, NULL, "dsp_mem"); 677 + mem = rproc_mem_entry_init(dev, NULL, (dma_addr_t)att->sa, 678 + att->size, da, imx_dsp_rproc_mem_alloc, 679 + imx_dsp_rproc_mem_release, "dsp_mem"); 710 680 711 681 if (mem) 712 682 rproc_coredump_add_segment(rproc, da, att->size); ··· 729 709 if (imx_dsp_rproc_sys_to_da(priv, res.start, resource_size(&res), &da)) 730 710 return -EINVAL; 731 711 732 - cpu_addr = devm_ioremap_resource_wc(dev, &res); 733 - if (IS_ERR(cpu_addr)) { 734 - dev_err(dev, "failed to map memory %pR\n", &res); 735 - return PTR_ERR(cpu_addr); 736 - } 737 - 738 712 /* Register memory region */ 739 - mem = rproc_mem_entry_init(dev, (void __force *)cpu_addr, (dma_addr_t)res.start, 740 - resource_size(&res), da, NULL, NULL, 713 + mem = rproc_mem_entry_init(dev, NULL, (dma_addr_t)res.start, 714 + resource_size(&res), da, 715 + imx_dsp_rproc_mem_alloc, 716 + imx_dsp_rproc_mem_release, 741 717 "%.*s", strchrnul(res.name, '@') - res.name, res.name); 742 718 if (!mem) 743 719 return -ENOMEM; ··· 1000 984 * Clear buffers after pm rumtime for internal ocram is not 1001 985 * accessible if power and clock are not enabled. 1002 986 */ 1003 - list_for_each_entry(carveout, &rproc->carveouts, node) { 1004 - if (carveout->va) 1005 - memset(carveout->va, 0, carveout->len); 987 + if (rproc->state == RPROC_OFFLINE) { 988 + list_for_each_entry(carveout, &rproc->carveouts, node) { 989 + if (carveout->va) 990 + memset(carveout->va, 0, carveout->len); 991 + } 1006 992 } 1007 993 1008 994 ret = imx_dsp_rproc_elf_load_segments(rproc, fw); ··· 1149 1131 priv = rproc->priv; 1150 1132 priv->rproc = rproc; 1151 1133 priv->dsp_dcfg = dsp_dcfg; 1152 - /* By default, host waits for fw_ready reply */ 1153 - priv->flags |= WAIT_FW_READY; 1134 + /* By default, host waits for fw_confirmation reply */ 1135 + priv->flags |= WAIT_FW_CONFIRMATION; 1154 1136 1155 1137 if (no_mailboxes) 1156 1138 imx_dsp_rproc_mbox_init = imx_dsp_rproc_mbox_no_alloc; ··· 1259 1241 1260 1242 if (rproc->state != RPROC_RUNNING) 1261 1243 goto out; 1244 + 1245 + /* 1246 + * No channel available for sending messages; 1247 + * indicates no mailboxes present, so trigger PM runtime suspend 1248 + */ 1249 + if (!priv->tx_ch) { 1250 + dev_dbg(dev, "No initialized mbox tx channel, suspend directly.\n"); 1251 + goto out; 1252 + } 1253 + 1254 + /* No fw confirmation expected, so trigger PM runtime suspend */ 1255 + if (!(priv->flags & WAIT_FW_CONFIRMATION)) { 1256 + dev_dbg(dev, "No FW_CONFIRMATION needed, suspend directly.\n"); 1257 + goto out; 1258 + } 1262 1259 1263 1260 reinit_completion(&priv->pm_comp); 1264 1261
+242 -15
drivers/remoteproc/imx_rproc.c
··· 8 8 #include <linux/clk.h> 9 9 #include <linux/err.h> 10 10 #include <linux/firmware/imx/sci.h> 11 + #include <linux/firmware/imx/sm.h> 11 12 #include <linux/interrupt.h> 12 13 #include <linux/kernel.h> 13 14 #include <linux/mailbox_client.h> ··· 23 22 #include <linux/reboot.h> 24 23 #include <linux/regmap.h> 25 24 #include <linux/remoteproc.h> 25 + #include <linux/scmi_imx_protocol.h> 26 26 #include <linux/workqueue.h> 27 27 28 28 #include "imx_rproc.h" ··· 94 92 #define ATT_CORE_MASK 0xffff 95 93 #define ATT_CORE(I) BIT((I)) 96 94 95 + /* Linux has permission to handle the Logical Machine of remote cores */ 96 + #define IMX_RPROC_FLAGS_SM_LMM_CTRL BIT(0) 97 + 97 98 static int imx_rproc_xtr_mbox_init(struct rproc *rproc, bool tx_block); 98 99 static void imx_rproc_free_mbox(void *data); 100 + 101 + /* Forward declarations for platform operations */ 102 + static const struct imx_rproc_plat_ops imx_rproc_ops_sm_lmm; 103 + static const struct imx_rproc_plat_ops imx_rproc_ops_sm_cpu; 99 104 100 105 struct imx_rproc { 101 106 struct device *dev; ··· 125 116 u32 entry; /* cpu start address */ 126 117 u32 core_index; 127 118 struct dev_pm_domain_list *pd_list; 119 + const struct imx_rproc_plat_ops *ops; 120 + /* 121 + * For i.MX System Manager based systems 122 + * BIT 0: IMX_RPROC_FLAGS_SM_LMM_CTRL(RPROC LM is under Linux control ) 123 + */ 124 + u32 flags; 125 + }; 126 + 127 + static const struct imx_rproc_att imx_rproc_att_imx95_m7[] = { 128 + /* dev addr , sys addr , size , flags */ 129 + /* TCM CODE NON-SECURE */ 130 + { 0x00000000, 0x203C0000, 0x00040000, ATT_OWN | ATT_IOMEM }, 131 + 132 + /* TCM SYS NON-SECURE*/ 133 + { 0x20000000, 0x20400000, 0x00040000, ATT_OWN | ATT_IOMEM }, 134 + 135 + /* DDR */ 136 + { 0x80000000, 0x80000000, 0x50000000, 0 }, 128 137 }; 129 138 130 139 static const struct imx_rproc_att imx_rproc_att_imx93[] = { ··· 339 312 return imx_sc_pm_cpu_start(priv->ipc_handle, priv->rsrc_id, true, priv->entry); 340 313 } 341 314 342 - static int imx_rproc_start(struct rproc *rproc) 315 + static int imx_rproc_sm_cpu_start(struct rproc *rproc) 343 316 { 344 317 struct imx_rproc *priv = rproc->priv; 345 318 const struct imx_rproc_dcfg *dcfg = priv->dcfg; 319 + int ret; 320 + 321 + ret = scmi_imx_cpu_reset_vector_set(dcfg->cpuid, 0, true, false, false); 322 + if (ret) { 323 + dev_err(priv->dev, "Failed to set reset vector cpuid(%u): %d\n", dcfg->cpuid, ret); 324 + return ret; 325 + } 326 + 327 + return scmi_imx_cpu_start(dcfg->cpuid, true); 328 + } 329 + 330 + static int imx_rproc_sm_lmm_start(struct rproc *rproc) 331 + { 332 + struct imx_rproc *priv = rproc->priv; 333 + const struct imx_rproc_dcfg *dcfg = priv->dcfg; 334 + struct device *dev = priv->dev; 335 + int ret; 336 + 337 + /* 338 + * If the remoteproc core can't start the M7, it will already be 339 + * handled in imx_rproc_sm_lmm_prepare(). 340 + */ 341 + ret = scmi_imx_lmm_reset_vector_set(dcfg->lmid, dcfg->cpuid, 0, 0); 342 + if (ret) { 343 + dev_err(dev, "Failed to set reset vector lmid(%u), cpuid(%u): %d\n", 344 + dcfg->lmid, dcfg->cpuid, ret); 345 + return ret; 346 + } 347 + 348 + ret = scmi_imx_lmm_operation(dcfg->lmid, SCMI_IMX_LMM_BOOT, 0); 349 + if (ret) { 350 + dev_err(dev, "Failed to boot lmm(%d): %d\n", dcfg->lmid, ret); 351 + return ret; 352 + } 353 + 354 + return 0; 355 + } 356 + 357 + static int imx_rproc_start(struct rproc *rproc) 358 + { 359 + struct imx_rproc *priv = rproc->priv; 346 360 struct device *dev = priv->dev; 347 361 int ret; 348 362 ··· 391 323 if (ret) 392 324 return ret; 393 325 394 - if (!dcfg->ops || !dcfg->ops->start) 326 + if (!priv->ops || !priv->ops->start) 395 327 return -EOPNOTSUPP; 396 328 397 - ret = dcfg->ops->start(rproc); 329 + ret = priv->ops->start(rproc); 398 330 if (ret) 399 331 dev_err(dev, "Failed to enable remote core!\n"); 400 332 ··· 437 369 return imx_sc_pm_cpu_start(priv->ipc_handle, priv->rsrc_id, false, priv->entry); 438 370 } 439 371 440 - static int imx_rproc_stop(struct rproc *rproc) 372 + static int imx_rproc_sm_cpu_stop(struct rproc *rproc) 441 373 { 442 374 struct imx_rproc *priv = rproc->priv; 443 375 const struct imx_rproc_dcfg *dcfg = priv->dcfg; 376 + 377 + return scmi_imx_cpu_start(dcfg->cpuid, false); 378 + } 379 + 380 + static int imx_rproc_sm_lmm_stop(struct rproc *rproc) 381 + { 382 + struct imx_rproc *priv = rproc->priv; 383 + const struct imx_rproc_dcfg *dcfg = priv->dcfg; 384 + 385 + if (!(priv->flags & IMX_RPROC_FLAGS_SM_LMM_CTRL)) 386 + return -EACCES; 387 + 388 + return scmi_imx_lmm_operation(dcfg->lmid, SCMI_IMX_LMM_SHUTDOWN, 0); 389 + } 390 + 391 + static int imx_rproc_stop(struct rproc *rproc) 392 + { 393 + struct imx_rproc *priv = rproc->priv; 444 394 struct device *dev = priv->dev; 445 395 int ret; 446 396 447 - if (!dcfg->ops || !dcfg->ops->stop) 397 + if (!priv->ops || !priv->ops->stop) 448 398 return -EOPNOTSUPP; 449 399 450 - ret = dcfg->ops->stop(rproc); 400 + ret = priv->ops->stop(rproc); 451 401 if (ret) 452 402 dev_err(dev, "Failed to stop remote core\n"); 453 403 else ··· 572 486 return 0; 573 487 } 574 488 489 + static int imx_rproc_sm_lmm_prepare(struct rproc *rproc) 490 + { 491 + struct imx_rproc *priv = rproc->priv; 492 + const struct imx_rproc_dcfg *dcfg = priv->dcfg; 493 + int ret; 494 + 495 + /* 496 + * IMX_RPROC_FLAGS_SM_LMM_CTRL not set indicates Linux is not able 497 + * to start/stop M7, then if rproc is not in detached state, 498 + * prepare should fail. If in detached state, this is in rproc_attach() 499 + * path. 500 + */ 501 + if (rproc->state == RPROC_DETACHED) 502 + return 0; 503 + 504 + if (!(priv->flags & IMX_RPROC_FLAGS_SM_LMM_CTRL)) 505 + return -EACCES; 506 + 507 + /* Power on the Logical Machine to make sure TCM is available. */ 508 + ret = scmi_imx_lmm_operation(dcfg->lmid, SCMI_IMX_LMM_POWER_ON, 0); 509 + if (ret) { 510 + dev_err(priv->dev, "Failed to power on lmm(%d): %d\n", dcfg->lmid, ret); 511 + return ret; 512 + } 513 + 514 + dev_info(priv->dev, "lmm(%d) powered on by Linux\n", dcfg->lmid); 515 + 516 + return 0; 517 + } 518 + 575 519 static int imx_rproc_prepare(struct rproc *rproc) 576 520 { 577 521 struct imx_rproc *priv = rproc->priv; ··· 644 528 rproc_coredump_add_segment(rproc, da, resource_size(&res)); 645 529 rproc_add_carveout(rproc, mem); 646 530 } 531 + 532 + if (priv->ops && priv->ops->prepare) 533 + return priv->ops->prepare(rproc); 534 + 535 + return 0; 647 536 } 648 537 649 538 static int imx_rproc_parse_fw(struct rproc *rproc, const struct firmware *fw) ··· 705 584 static int imx_rproc_detach(struct rproc *rproc) 706 585 { 707 586 struct imx_rproc *priv = rproc->priv; 708 - const struct imx_rproc_dcfg *dcfg = priv->dcfg; 709 587 710 - if (!dcfg->ops || !dcfg->ops->detach) 588 + if (!priv->ops || !priv->ops->detach) 711 589 return -EOPNOTSUPP; 712 590 713 - return dcfg->ops->detach(rproc); 591 + return priv->ops->detach(rproc); 714 592 } 715 593 716 594 static struct resource_table *imx_rproc_get_loaded_rsc_table(struct rproc *rproc, size_t *table_sz) ··· 728 608 imx_rproc_elf_find_loaded_rsc_table(struct rproc *rproc, const struct firmware *fw) 729 609 { 730 610 struct imx_rproc *priv = rproc->priv; 611 + 612 + /* No resource table in the firmware */ 613 + if (!rproc->table_ptr) 614 + return NULL; 731 615 732 616 if (priv->rsc_table) 733 617 return (struct resource_table *)priv->rsc_table; ··· 818 694 } 819 695 priv->mem[b].sys_addr = res.start; 820 696 priv->mem[b].size = resource_size(&res); 821 - if (!strcmp(res.name, "rsc-table")) 697 + if (strstarts(res.name, "rsc-table")) 822 698 priv->rsc_table = priv->mem[b].cpu_addr; 823 699 b++; 824 700 } ··· 1101 977 return 0; 1102 978 } 1103 979 1104 - static int imx_rproc_detect_mode(struct imx_rproc *priv) 980 + /* Check whether remoteproc core is responsible for M7 lifecycle */ 981 + static int imx_rproc_sm_lmm_check(struct rproc *rproc, bool started) 1105 982 { 983 + struct imx_rproc *priv = rproc->priv; 1106 984 const struct imx_rproc_dcfg *dcfg = priv->dcfg; 985 + struct device *dev = priv->dev; 986 + int ret; 987 + 988 + ret = scmi_imx_lmm_operation(dcfg->lmid, SCMI_IMX_LMM_POWER_ON, 0); 989 + if (ret) { 990 + if (ret == -EACCES) { 991 + /* 992 + * M7 is booted before Linux and not under Linux Control, so only 993 + * do IPC between RPROC and Linux, not return failure 994 + */ 995 + dev_info(dev, "lmm(%d) not under Linux Control\n", dcfg->lmid); 996 + return 0; 997 + } 998 + 999 + dev_err(dev, "power on lmm(%d) failed: %d\n", dcfg->lmid, ret); 1000 + return ret; 1001 + } 1002 + 1003 + /* Shutdown remote processor if not started */ 1004 + if (!started) { 1005 + ret = scmi_imx_lmm_operation(dcfg->lmid, SCMI_IMX_LMM_SHUTDOWN, 0); 1006 + if (ret) { 1007 + dev_err(dev, "shutdown lmm(%d) failed: %d\n", dcfg->lmid, ret); 1008 + return ret; 1009 + } 1010 + } 1011 + 1012 + priv->flags |= IMX_RPROC_FLAGS_SM_LMM_CTRL; 1013 + 1014 + return 0; 1015 + } 1016 + 1017 + static int imx_rproc_sm_detect_mode(struct rproc *rproc) 1018 + { 1019 + struct imx_rproc *priv = rproc->priv; 1020 + const struct imx_rproc_dcfg *dcfg = priv->dcfg; 1021 + struct device *dev = priv->dev; 1022 + struct scmi_imx_lmm_info info; 1023 + bool started = false; 1024 + int ret; 1025 + 1026 + ret = scmi_imx_cpu_started(dcfg->cpuid, &started); 1027 + if (ret) { 1028 + dev_err(dev, "Failed to detect cpu(%d) status: %d\n", dcfg->cpuid, ret); 1029 + return ret; 1030 + } 1031 + 1032 + if (started) 1033 + priv->rproc->state = RPROC_DETACHED; 1034 + 1035 + /* Get current Linux Logical Machine ID */ 1036 + ret = scmi_imx_lmm_info(LMM_ID_DISCOVER, &info); 1037 + if (ret) { 1038 + dev_err(dev, "Failed to get current LMM ID err: %d\n", ret); 1039 + return ret; 1040 + } 1107 1041 1108 1042 /* 1109 - * To i.MX{7,8} ULP, Linux is under control of RTOS, no need 1110 - * dcfg->ops or dcfg->ops->detect_mode, it is state RPROC_DETACHED. 1043 + * Check whether M7 is in the same LM as host core(running Linux) 1044 + * If yes, use CPU protocol API to manage M7. 1045 + * If no, use Logical Machine API to manage M7. 1111 1046 */ 1112 - if (!dcfg->ops || !dcfg->ops->detect_mode) { 1047 + if (dcfg->lmid == info.lmid) { 1048 + priv->ops = &imx_rproc_ops_sm_cpu; 1049 + dev_info(dev, "Using CPU Protocol OPS\n"); 1050 + return 0; 1051 + } 1052 + 1053 + priv->ops = &imx_rproc_ops_sm_lmm; 1054 + dev_info(dev, "Using LMM Protocol OPS\n"); 1055 + 1056 + return imx_rproc_sm_lmm_check(rproc, started); 1057 + } 1058 + 1059 + static int imx_rproc_detect_mode(struct imx_rproc *priv) 1060 + { 1061 + /* 1062 + * To i.MX{7,8} ULP, Linux is under control of RTOS, no need 1063 + * priv->ops or priv->ops->detect_mode, it is state RPROC_DETACHED. 1064 + */ 1065 + if (!priv->ops || !priv->ops->detect_mode) { 1113 1066 priv->rproc->state = RPROC_DETACHED; 1114 1067 return 0; 1115 1068 } 1116 1069 1117 - return dcfg->ops->detect_mode(priv->rproc); 1070 + return priv->ops->detect_mode(priv->rproc); 1118 1071 } 1119 1072 1120 1073 static int imx_rproc_sys_off_handler(struct sys_off_data *data) ··· 1240 1039 priv->rproc = rproc; 1241 1040 priv->dcfg = dcfg; 1242 1041 priv->dev = dev; 1042 + 1043 + if (dcfg->ops) 1044 + priv->ops = dcfg->ops; 1243 1045 1244 1046 dev_set_drvdata(dev, rproc); 1245 1047 priv->workqueue = create_workqueue(dev_name(dev)); ··· 1355 1151 .detect_mode = imx_rproc_scu_api_detect_mode, 1356 1152 }; 1357 1153 1154 + static const struct imx_rproc_plat_ops imx_rproc_ops_sm_lmm = { 1155 + .detect_mode = imx_rproc_sm_detect_mode, 1156 + .prepare = imx_rproc_sm_lmm_prepare, 1157 + .start = imx_rproc_sm_lmm_start, 1158 + .stop = imx_rproc_sm_lmm_stop, 1159 + }; 1160 + 1161 + static const struct imx_rproc_plat_ops imx_rproc_ops_sm_cpu = { 1162 + .detect_mode = imx_rproc_sm_detect_mode, 1163 + .start = imx_rproc_sm_cpu_start, 1164 + .stop = imx_rproc_sm_cpu_stop, 1165 + }; 1166 + 1358 1167 static const struct imx_rproc_dcfg imx_rproc_cfg_imx8mn_mmio = { 1359 1168 .src_reg = IMX7D_SRC_SCR, 1360 1169 .src_mask = IMX7D_M4_RST_MASK, ··· 1451 1234 .flags = IMX_RPROC_NEED_CLKS, 1452 1235 }; 1453 1236 1237 + static const struct imx_rproc_dcfg imx_rproc_cfg_imx95_m7 = { 1238 + .att = imx_rproc_att_imx95_m7, 1239 + .att_size = ARRAY_SIZE(imx_rproc_att_imx95_m7), 1240 + .ops = &imx_rproc_ops_sm_lmm, 1241 + /* Must align with System Manager Firmware */ 1242 + .cpuid = 1, /* Use 1 as cpu id for M7 core */ 1243 + .lmid = 1, /* Use 1 as Logical Machine ID where M7 resides */ 1244 + }; 1245 + 1454 1246 static const struct of_device_id imx_rproc_of_match[] = { 1455 1247 { .compatible = "fsl,imx7ulp-cm4", .data = &imx_rproc_cfg_imx7ulp }, 1456 1248 { .compatible = "fsl,imx7d-cm4", .data = &imx_rproc_cfg_imx7d }, ··· 1474 1248 { .compatible = "fsl,imx8qm-cm4", .data = &imx_rproc_cfg_imx8qm }, 1475 1249 { .compatible = "fsl,imx8ulp-cm33", .data = &imx_rproc_cfg_imx8ulp }, 1476 1250 { .compatible = "fsl,imx93-cm33", .data = &imx_rproc_cfg_imx93 }, 1251 + { .compatible = "fsl,imx95-cm7", .data = &imx_rproc_cfg_imx95_m7 }, 1477 1252 {}, 1478 1253 }; 1479 1254 MODULE_DEVICE_TABLE(of, imx_rproc_of_match);
+4
drivers/remoteproc/imx_rproc.h
··· 24 24 int (*stop)(struct rproc *rproc); 25 25 int (*detach)(struct rproc *rproc); 26 26 int (*detect_mode)(struct rproc *rproc); 27 + int (*prepare)(struct rproc *rproc); 27 28 }; 28 29 29 30 struct imx_rproc_dcfg { ··· 38 37 size_t att_size; 39 38 u32 flags; 40 39 const struct imx_rproc_plat_ops *ops; 40 + /* For System Manager(SM) based SoCs */ 41 + u32 cpuid; /* ID of the remote core */ 42 + u32 lmid; /* ID of the Logcial Machine */ 41 43 }; 42 44 43 45 #endif /* _IMX_RPROC_H */
+29 -17
drivers/remoteproc/mtk_scp.c
··· 283 283 struct mtk_scp *scp = priv; 284 284 int ret; 285 285 286 - ret = clk_prepare_enable(scp->clk); 286 + ret = clk_enable(scp->clk); 287 287 if (ret) { 288 288 dev_err(scp->dev, "failed to enable clocks\n"); 289 289 return IRQ_NONE; ··· 291 291 292 292 scp->data->scp_irq_handler(scp); 293 293 294 - clk_disable_unprepare(scp->clk); 294 + clk_disable(scp->clk); 295 295 296 296 return IRQ_HANDLED; 297 297 } ··· 665 665 struct device *dev = scp->dev; 666 666 int ret; 667 667 668 - ret = clk_prepare_enable(scp->clk); 668 + ret = clk_enable(scp->clk); 669 669 if (ret) { 670 670 dev_err(dev, "failed to enable clocks\n"); 671 671 return ret; ··· 680 680 681 681 ret = scp_elf_load_segments(rproc, fw); 682 682 leave: 683 - clk_disable_unprepare(scp->clk); 683 + clk_disable(scp->clk); 684 684 685 685 return ret; 686 686 } ··· 691 691 struct device *dev = scp->dev; 692 692 int ret; 693 693 694 - ret = clk_prepare_enable(scp->clk); 694 + ret = clk_enable(scp->clk); 695 695 if (ret) { 696 696 dev_err(dev, "failed to enable clocks\n"); 697 697 return ret; 698 698 } 699 699 700 700 ret = scp_ipi_init(scp, fw); 701 - clk_disable_unprepare(scp->clk); 701 + clk_disable(scp->clk); 702 702 return ret; 703 703 } 704 704 ··· 709 709 struct scp_run *run = &scp->run; 710 710 int ret; 711 711 712 - ret = clk_prepare_enable(scp->clk); 712 + ret = clk_enable(scp->clk); 713 713 if (ret) { 714 714 dev_err(dev, "failed to enable clocks\n"); 715 715 return ret; ··· 734 734 goto stop; 735 735 } 736 736 737 - clk_disable_unprepare(scp->clk); 737 + clk_disable(scp->clk); 738 738 dev_info(dev, "SCP is ready. FW version %s\n", run->fw_ver); 739 739 740 740 return 0; 741 741 742 742 stop: 743 743 scp->data->scp_reset_assert(scp); 744 - clk_disable_unprepare(scp->clk); 744 + clk_disable(scp->clk); 745 745 return ret; 746 746 } 747 747 ··· 909 909 struct mtk_scp *scp = rproc->priv; 910 910 int ret; 911 911 912 - ret = clk_prepare_enable(scp->clk); 912 + ret = clk_enable(scp->clk); 913 913 if (ret) { 914 914 dev_err(scp->dev, "failed to enable clocks\n"); 915 915 return ret; ··· 917 917 918 918 scp->data->scp_reset_assert(scp); 919 919 scp->data->scp_stop(scp); 920 - clk_disable_unprepare(scp->clk); 920 + clk_disable(scp->clk); 921 921 922 922 return 0; 923 923 } 924 924 925 + static int scp_prepare(struct rproc *rproc) 926 + { 927 + struct mtk_scp *scp = rproc->priv; 928 + 929 + return clk_prepare(scp->clk); 930 + } 931 + 932 + static int scp_unprepare(struct rproc *rproc) 933 + { 934 + struct mtk_scp *scp = rproc->priv; 935 + 936 + clk_unprepare(scp->clk); 937 + return 0; 938 + } 939 + 925 940 static const struct rproc_ops scp_ops = { 941 + .prepare = scp_prepare, 942 + .unprepare = scp_unprepare, 926 943 .start = scp_start, 927 944 .stop = scp_stop, 928 945 .load = scp_load, ··· 1304 1287 struct device *dev = &pdev->dev; 1305 1288 struct device_node *np = dev_of_node(dev); 1306 1289 struct platform_device *cpdev; 1307 - struct device_node *child; 1308 1290 struct list_head *scp_list = &scp_cluster->mtk_scp_list; 1309 1291 const struct mtk_scp_of_data **cluster_of_data; 1310 1292 struct mtk_scp *scp, *temp; ··· 1312 1296 1313 1297 cluster_of_data = (const struct mtk_scp_of_data **)of_device_get_match_data(dev); 1314 1298 1315 - for_each_available_child_of_node(np, child) { 1299 + for_each_available_child_of_node_scoped(np, child) { 1316 1300 if (!cluster_of_data[core_id]) { 1317 1301 ret = -EINVAL; 1318 1302 dev_err(dev, "Not support core %d\n", core_id); 1319 - of_node_put(child); 1320 1303 goto init_fail; 1321 1304 } 1322 1305 ··· 1323 1308 if (!cpdev) { 1324 1309 ret = -ENODEV; 1325 1310 dev_err(dev, "Not found platform device for core %d\n", core_id); 1326 - of_node_put(child); 1327 1311 goto init_fail; 1328 1312 } 1329 1313 ··· 1331 1317 if (IS_ERR(scp)) { 1332 1318 ret = PTR_ERR(scp); 1333 1319 dev_err(dev, "Failed to initialize core %d rproc\n", core_id); 1334 - of_node_put(child); 1335 1320 goto init_fail; 1336 1321 } 1337 1322 1338 1323 ret = rproc_add(scp->rproc); 1339 1324 if (ret) { 1340 1325 dev_err(dev, "Failed to add rproc of core %d\n", core_id); 1341 - of_node_put(child); 1342 1326 scp_free(scp); 1343 1327 goto init_fail; 1344 1328 }
+2 -2
drivers/remoteproc/mtk_scp_ipi.c
··· 171 171 WARN_ON(len > scp_sizes->ipi_share_buffer_size) || WARN_ON(!buf)) 172 172 return -EINVAL; 173 173 174 - ret = clk_prepare_enable(scp->clk); 174 + ret = clk_enable(scp->clk); 175 175 if (ret) { 176 176 dev_err(scp->dev, "failed to enable clock\n"); 177 177 return ret; ··· 211 211 212 212 unlock_mutex: 213 213 mutex_unlock(&scp->send_lock); 214 - clk_disable_unprepare(scp->clk); 214 + clk_disable(scp->clk); 215 215 216 216 return ret; 217 217 }
+2 -7
drivers/remoteproc/xlnx_r5_remoteproc.c
··· 1271 1271 struct zynqmp_r5_core **r5_cores; 1272 1272 enum rpu_oper_mode fw_reg_val; 1273 1273 struct device **child_devs; 1274 - struct device_node *child; 1275 1274 enum rpu_tcm_comb tcm_mode; 1276 1275 int core_count, ret, i; 1277 1276 struct mbox_info *ipi; ··· 1349 1350 } 1350 1351 1351 1352 i = 0; 1352 - for_each_available_child_of_node(dev_node, child) { 1353 + for_each_available_child_of_node_scoped(dev_node, child) { 1353 1354 child_pdev = of_find_device_by_node(child); 1354 1355 if (!child_pdev) { 1355 - of_node_put(child); 1356 1356 ret = -ENODEV; 1357 1357 goto release_r5_cores; 1358 1358 } ··· 1361 1363 /* create and add remoteproc instance of type struct rproc */ 1362 1364 r5_cores[i] = zynqmp_r5_add_rproc_core(&child_pdev->dev); 1363 1365 if (IS_ERR(r5_cores[i])) { 1364 - of_node_put(child); 1365 1366 ret = PTR_ERR(r5_cores[i]); 1366 1367 r5_cores[i] = NULL; 1367 1368 goto release_r5_cores; ··· 1380 1383 * If two child nodes are available in dts in lockstep mode, 1381 1384 * then ignore second child node. 1382 1385 */ 1383 - if (cluster_mode == LOCKSTEP_MODE) { 1384 - of_node_put(child); 1386 + if (cluster_mode == LOCKSTEP_MODE) 1385 1387 break; 1386 - } 1387 1388 1388 1389 i++; 1389 1390 }