Merge tag 'rproc-v6.2' of git://git.kernel.org/pub/scm/linux/kernel/git/remoteproc...
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 21 Dec 2022 17:37:14 +0000 (09:37 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 21 Dec 2022 17:37:14 +0000 (09:37 -0800)
Pull remoteproc updates from Bjorn Andersson:
 "rproc-virtio device names are now auto generated, to avoid conflicts
  between remoteproc instances.

  The imx_rproc driver is extended with support for communicating with
  and attaching to a running M4 on i.MX8QXP, as well as support for
  attaching to the M4 after self-recovering from a crash. Support is
  added for i.MX8QM and mailbox channels are reconnected during the
  recovery process, in order to avoid data corruption.

  The Xilinx Zynqmp firmware interface is extended and support for the
  Xilinx R5 RPU is introduced.

  Various resources leaks, primarily in error paths, throughout the
  Qualcomm drivers are corrected.

  Lastly a fix to ensure that pm_relax is invoked even if the remoteproc
  instance is stopped between a crash is being reported and the recovery
  handler is scheduled"

* tag 'rproc-v6.2' of git://git.kernel.org/pub/scm/linux/kernel/git/remoteproc/linux: (25 commits)
  remoteproc: core: Do pm_relax when in RPROC_OFFLINE state
  remoteproc: qcom: q6v5: Fix missing clk_disable_unprepare() in q6v5_wcss_qcs404_power_on()
  remoteproc: qcom_q6v5_pas: Fix missing of_node_put() in adsp_alloc_memory_region()
  remoteproc: qcom_q6v5_pas: detach power domains on remove
  remoteproc: qcom_q6v5_pas: disable wakeup on probe fail or remove
  remoteproc: qcom: q6v5: Fix potential null-ptr-deref in q6v5_wcss_init_mmio()
  remoteproc: sysmon: fix memory leak in qcom_add_sysmon_subdev()
  remoteproc: sysmon: Make QMI message rules const
  drivers: remoteproc: Add Xilinx r5 remoteproc driver
  firmware: xilinx: Add RPU configuration APIs
  firmware: xilinx: Add shutdown/wakeup APIs
  firmware: xilinx: Add ZynqMP firmware ioctl enums for RPU configuration.
  arm64: dts: xilinx: zynqmp: Add RPU subsystem device node
  dt-bindings: remoteproc: Add Xilinx RPU subsystem bindings
  remoteproc: core: Use device_match_of_node()
  remoteproc: imx_rproc: Correct i.MX93 DRAM mapping
  remoteproc: imx_rproc: Enable attach recovery for i.MX8QM/QXP
  remoteproc: imx_rproc: Request mbox channel later
  remoteproc: imx_rproc: Support i.MX8QM
  remoteproc: imx_rproc: Support kicking Mcore from Linux for i.MX8QXP
  ...

1  2 
Documentation/devicetree/bindings/remoteproc/fsl,imx-rproc.yaml
arch/arm64/boot/dts/xilinx/zynqmp.dtsi
drivers/firmware/xilinx/zynqmp.c
include/linux/firmware/xlnx-zynqmp.h

@@@ -4,7 -4,7 +4,7 @@@
  $id: "http://devicetree.org/schemas/remoteproc/fsl,imx-rproc.yaml#"
  $schema: "http://devicetree.org/meta-schemas/core.yaml#"
  
 -title: NXP i.MX Co-Processor Bindings
 +title: NXP i.MX Co-Processor
  
  description:
    This binding provides support for ARM Cortex M4 Co-processor found on some NXP iMX SoCs.
@@@ -22,6 -22,8 +22,8 @@@ properties
        - fsl,imx8mn-cm7
        - fsl,imx8mp-cm7
        - fsl,imx8mq-cm4
+       - fsl,imx8qm-cm4
+       - fsl,imx8qxp-cm4
        - fsl,imx8ulp-cm33
        - fsl,imx93-cm33
  
      minItems: 1
      maxItems: 32
  
+   power-domains:
+     maxItems: 8
    fsl,auto-boot:
      $ref: /schemas/types.yaml#/definitions/flag
      description:
        Indicate whether need to load the default firmware and start the remote
        processor automatically.
  
+   fsl,entry-address:
+     $ref: /schemas/types.yaml#/definitions/uint32
+     description:
+       Specify CPU entry address for SCU enabled processor.
+   fsl,resource-id:
+     $ref: /schemas/types.yaml#/definitions/uint32
+     description:
+       This property is to specify the resource id of the remote processor in SoC
+       which supports SCFW
  required:
    - compatible
  
                };
        };
  
+       reserved-memory {
+               #address-cells = <2>;
+               #size-cells = <2>;
+               ranges;
+               rproc_0_fw_image: memory@3ed00000 {
+                       no-map;
+                       reg = <0x0 0x3ed00000 0x0 0x40000>;
+               };
+               rproc_1_fw_image: memory@3ef00000 {
+                       no-map;
+                       reg = <0x0 0x3ef00000 0x0 0x40000>;
+               };
+       };
        zynqmp_ipi: zynqmp_ipi {
                compatible = "xlnx,zynqmp-ipi-mailbox";
                interrupt-parent = <&gic>;
                ranges;
        };
  
+       remoteproc {
+               compatible = "xlnx,zynqmp-r5fss";
+               xlnx,cluster-mode = <1>;
+               r5f-0 {
+                       compatible = "xlnx,zynqmp-r5f";
+                       power-domains = <&zynqmp_firmware PD_RPU_0>;
+                       memory-region = <&rproc_0_fw_image>;
+               };
+               r5f-1 {
+                       compatible = "xlnx,zynqmp-r5f";
+                       power-domains = <&zynqmp_firmware PD_RPU_1>;
+                       memory-region = <&rproc_1_fw_image>;
+               };
+       };
        amba: axi {
                compatible = "simple-bus";
                #address-cells = <2>;
                               <&zynqmp_dpdma ZYNQMP_DPDMA_VIDEO1>,
                               <&zynqmp_dpdma ZYNQMP_DPDMA_VIDEO2>,
                               <&zynqmp_dpdma ZYNQMP_DPDMA_GRAPHICS>;
 +
 +                      ports {
 +                              #address-cells = <1>;
 +                              #size-cells = <0>;
 +
 +                              port@0 {
 +                                      reg = <0>;
 +                              };
 +                              port@1 {
 +                                      reg = <1>;
 +                              };
 +                              port@2 {
 +                                      reg = <2>;
 +                              };
 +                              port@3 {
 +                                      reg = <3>;
 +                              };
 +                              port@4 {
 +                                      reg = <4>;
 +                              };
 +                              port@5 {
 +                                      reg = <5>;
 +                              };
 +                      };
                };
        };
  };
@@@ -843,13 -843,6 +843,13 @@@ int zynqmp_pm_read_pggs(u32 index, u32 
  }
  EXPORT_SYMBOL_GPL(zynqmp_pm_read_pggs);
  
 +int zynqmp_pm_set_tapdelay_bypass(u32 index, u32 value)
 +{
 +      return zynqmp_pm_invoke_fn(PM_IOCTL, 0, IOCTL_SET_TAPDELAY_BYPASS,
 +                                 index, value, NULL);
 +}
 +EXPORT_SYMBOL_GPL(zynqmp_pm_set_tapdelay_bypass);
 +
  /**
   * zynqmp_pm_set_boot_health_status() - PM API for setting healthy boot status
   * @value:    Status value to be written
@@@ -1167,6 -1160,103 +1167,103 @@@ int zynqmp_pm_release_node(const u32 no
  EXPORT_SYMBOL_GPL(zynqmp_pm_release_node);
  
  /**
+  * zynqmp_pm_get_rpu_mode() - Get RPU mode
+  * @node_id:  Node ID of the device
+  * @rpu_mode: return by reference value
+  *            either split or lockstep
+  *
+  * Return:    return 0 on success or error+reason.
+  *            if success, then  rpu_mode will be set
+  *            to current rpu mode.
+  */
+ int zynqmp_pm_get_rpu_mode(u32 node_id, enum rpu_oper_mode *rpu_mode)
+ {
+       u32 ret_payload[PAYLOAD_ARG_CNT];
+       int ret;
+       ret = zynqmp_pm_invoke_fn(PM_IOCTL, node_id,
+                                 IOCTL_GET_RPU_OPER_MODE, 0, 0, ret_payload);
+       /* only set rpu_mode if no error */
+       if (ret == XST_PM_SUCCESS)
+               *rpu_mode = ret_payload[0];
+       return ret;
+ }
+ EXPORT_SYMBOL_GPL(zynqmp_pm_get_rpu_mode);
+ /**
+  * zynqmp_pm_set_rpu_mode() - Set RPU mode
+  * @node_id:  Node ID of the device
+  * @rpu_mode: Argument 1 to requested IOCTL call. either split or lockstep
+  *
+  *            This function is used to set RPU mode to split or
+  *            lockstep
+  *
+  * Return:    Returns status, either success or error+reason
+  */
+ int zynqmp_pm_set_rpu_mode(u32 node_id, enum rpu_oper_mode rpu_mode)
+ {
+       return zynqmp_pm_invoke_fn(PM_IOCTL, node_id,
+                                  IOCTL_SET_RPU_OPER_MODE, (u32)rpu_mode,
+                                  0, NULL);
+ }
+ EXPORT_SYMBOL_GPL(zynqmp_pm_set_rpu_mode);
+ /**
+  * zynqmp_pm_set_tcm_config - configure TCM
+  * @node_id:  Firmware specific TCM subsystem ID
+  * @tcm_mode: Argument 1 to requested IOCTL call
+  *              either PM_RPU_TCM_COMB or PM_RPU_TCM_SPLIT
+  *
+  * This function is used to set RPU mode to split or combined
+  *
+  * Return: status: 0 for success, else failure
+  */
+ int zynqmp_pm_set_tcm_config(u32 node_id, enum rpu_tcm_comb tcm_mode)
+ {
+       return zynqmp_pm_invoke_fn(PM_IOCTL, node_id,
+                                  IOCTL_TCM_COMB_CONFIG, (u32)tcm_mode, 0,
+                                  NULL);
+ }
+ EXPORT_SYMBOL_GPL(zynqmp_pm_set_tcm_config);
+ /**
+  * zynqmp_pm_force_pwrdwn - PM call to request for another PU or subsystem to
+  *             be powered down forcefully
+  * @node:  Node ID of the targeted PU or subsystem
+  * @ack:   Flag to specify whether acknowledge is requested
+  *
+  * Return: status, either success or error+reason
+  */
+ int zynqmp_pm_force_pwrdwn(const u32 node,
+                          const enum zynqmp_pm_request_ack ack)
+ {
+       return zynqmp_pm_invoke_fn(PM_FORCE_POWERDOWN, node, ack, 0, 0, NULL);
+ }
+ EXPORT_SYMBOL_GPL(zynqmp_pm_force_pwrdwn);
+ /**
+  * zynqmp_pm_request_wake - PM call to wake up selected master or subsystem
+  * @node:  Node ID of the master or subsystem
+  * @set_addr:  Specifies whether the address argument is relevant
+  * @address:   Address from which to resume when woken up
+  * @ack:   Flag to specify whether acknowledge requested
+  *
+  * Return: status, either success or error+reason
+  */
+ int zynqmp_pm_request_wake(const u32 node,
+                          const bool set_addr,
+                          const u64 address,
+                          const enum zynqmp_pm_request_ack ack)
+ {
+       /* set_addr flag is encoded into 1st bit of address */
+       return zynqmp_pm_invoke_fn(PM_REQUEST_WAKEUP, node, address | set_addr,
+                                  address >> 32, ack, NULL);
+ }
+ EXPORT_SYMBOL_GPL(zynqmp_pm_request_wake);
+ /**
   * zynqmp_pm_set_requirement() - PM call to set requirement for PM slaves
   * @node:             Node ID of the slave
   * @capabilities:     Requested capabilities of the slave
@@@ -12,6 -12,7 +12,7 @@@
  
  #ifndef __FIRMWARE_ZYNQMP_H__
  #define __FIRMWARE_ZYNQMP_H__
+ #include <linux/types.h>
  
  #include <linux/err.h>
  
@@@ -87,6 -88,8 +88,8 @@@ enum pm_api_cb_id 
  enum pm_api_id {
        PM_GET_API_VERSION = 1,
        PM_REGISTER_NOTIFIER = 5,
+       PM_FORCE_POWERDOWN = 8,
+       PM_REQUEST_WAKEUP = 10,
        PM_SYSTEM_SHUTDOWN = 12,
        PM_REQUEST_NODE = 13,
        PM_RELEASE_NODE = 14,
@@@ -135,7 -138,10 +138,11 @@@ enum pm_ret_status 
  };
  
  enum pm_ioctl_id {
+       IOCTL_GET_RPU_OPER_MODE = 0,
+       IOCTL_SET_RPU_OPER_MODE = 1,
+       IOCTL_RPU_BOOT_ADDR_CONFIG = 2,
+       IOCTL_TCM_COMB_CONFIG = 3,
 +      IOCTL_SET_TAPDELAY_BYPASS = 4,
        IOCTL_SD_DLL_RESET = 6,
        IOCTL_SET_SD_TAPDELAY = 7,
        IOCTL_SET_PLL_FRAC_MODE = 8,
@@@ -176,6 -182,21 +183,21 @@@ enum pm_query_id 
        PM_QID_CLOCK_GET_MAX_DIVISOR = 13,
  };
  
+ enum rpu_oper_mode {
+       PM_RPU_MODE_LOCKSTEP = 0,
+       PM_RPU_MODE_SPLIT = 1,
+ };
+ enum rpu_boot_mem {
+       PM_RPU_BOOTMEM_LOVEC = 0,
+       PM_RPU_BOOTMEM_HIVEC = 1,
+ };
+ enum rpu_tcm_comb {
+       PM_RPU_TCM_SPLIT = 0,
+       PM_RPU_TCM_COMB = 1,
+ };
  enum zynqmp_pm_reset_action {
        PM_RESET_ACTION_RELEASE = 0,
        PM_RESET_ACTION_ASSERT = 1,
@@@ -390,18 -411,6 +412,18 @@@ enum zynqmp_pm_shutdown_subtype 
        ZYNQMP_PM_SHUTDOWN_SUBTYPE_SYSTEM = 2,
  };
  
 +enum tap_delay_signal_type {
 +      PM_TAPDELAY_NAND_DQS_IN = 0,
 +      PM_TAPDELAY_NAND_DQS_OUT = 1,
 +      PM_TAPDELAY_QSPI = 2,
 +      PM_TAPDELAY_MAX = 3,
 +};
 +
 +enum tap_delay_bypass_ctrl {
 +      PM_TAPDELAY_BYPASS_DISABLE = 0,
 +      PM_TAPDELAY_BYPASS_ENABLE = 1,
 +};
 +
  enum ospi_mux_select_type {
        PM_OSPI_MUX_SEL_DMA = 0,
        PM_OSPI_MUX_SEL_LINEAR = 1,
@@@ -497,7 -506,6 +519,7 @@@ int zynqmp_pm_write_ggs(u32 index, u32 
  int zynqmp_pm_read_ggs(u32 index, u32 *value);
  int zynqmp_pm_write_pggs(u32 index, u32 value);
  int zynqmp_pm_read_pggs(u32 index, u32 *value);
 +int zynqmp_pm_set_tapdelay_bypass(u32 index, u32 value);
  int zynqmp_pm_system_shutdown(const u32 type, const u32 subtype);
  int zynqmp_pm_set_boot_health_status(u32 value);
  int zynqmp_pm_pinctrl_request(const u32 pin);
@@@ -516,6 -524,15 +538,15 @@@ int zynqmp_pm_is_function_supported(con
  int zynqmp_pm_set_feature_config(enum pm_feature_config_id id, u32 value);
  int zynqmp_pm_get_feature_config(enum pm_feature_config_id id, u32 *payload);
  int zynqmp_pm_register_sgi(u32 sgi_num, u32 reset);
+ int zynqmp_pm_force_pwrdwn(const u32 target,
+                          const enum zynqmp_pm_request_ack ack);
+ int zynqmp_pm_request_wake(const u32 node,
+                          const bool set_addr,
+                          const u64 address,
+                          const enum zynqmp_pm_request_ack ack);
+ int zynqmp_pm_get_rpu_mode(u32 node_id, enum rpu_oper_mode *rpu_mode);
+ int zynqmp_pm_set_rpu_mode(u32 node_id, u32 arg1);
+ int zynqmp_pm_set_tcm_config(u32 node_id, u32 arg1);
  int zynqmp_pm_set_sd_config(u32 node, enum pm_sd_config_type config, u32 value);
  int zynqmp_pm_set_gem_config(u32 node, enum pm_gem_config_type config,
                             u32 value);
@@@ -710,11 -727,6 +741,11 @@@ static inline int zynqmp_pm_read_pggs(u
        return -ENODEV;
  }
  
 +static inline int zynqmp_pm_set_tapdelay_bypass(u32 index, u32 value)
 +{
 +      return -ENODEV;
 +}
 +
  static inline int zynqmp_pm_system_shutdown(const u32 type, const u32 subtype)
  {
        return -ENODEV;
@@@ -795,6 -807,35 +826,35 @@@ static inline int zynqmp_pm_register_sg
        return -ENODEV;
  }
  
+ static inline int zynqmp_pm_force_pwrdwn(const u32 target,
+                                        const enum zynqmp_pm_request_ack ack)
+ {
+       return -ENODEV;
+ }
+ static inline int zynqmp_pm_request_wake(const u32 node,
+                                        const bool set_addr,
+                                        const u64 address,
+                                        const enum zynqmp_pm_request_ack ack)
+ {
+       return -ENODEV;
+ }
+ static inline int zynqmp_pm_get_rpu_mode(u32 node_id, enum rpu_oper_mode *rpu_mode)
+ {
+       return -ENODEV;
+ }
+ static inline int zynqmp_pm_set_rpu_mode(u32 node_id, u32 arg1)
+ {
+       return -ENODEV;
+ }
+ static inline int zynqmp_pm_set_tcm_config(u32 node_id, u32 arg1)
+ {
+       return -ENODEV;
+ }
  static inline int zynqmp_pm_set_sd_config(u32 node,
                                          enum pm_sd_config_type config,
                                          u32 value)