Commit ab7b884a authored by Linus Torvalds's avatar Linus Torvalds

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

Pull remoteproc updates from Bjorn Andersson:
 "This makes the remoteproc core rproc_class const.

  DeviceTree bindings for a few different Qualcomm remoteprocs are
  updated to remove a range of validation warnings/errors. The Qualcomm
  SMD binding marks qcom,ipc deprecated, in favor or the mailbox
  interface.

  The TI K3 R5 remoteproc driver is updated to ensure that cores are
  powered up in the appropriate order. The driver also see a couple of
  fixes related to cleanups in error paths during probe.

  The Mediatek remoteproc driver is extended to support the MT8188 SCP
  core 1. Support for varying DRAM and IPI shared buffer sizes are
  introduced. This together with a couple of bug fixes and improvements
  to the driver.

  Support for the AMD-Xilinx Versal and Versal-NET platforms are added.
  Coredump support and support for parsing TCM information from
  DeviceTree is added to the Xilinx R5F remoteproc driver"

* tag 'rproc-v6.10' of git://git.kernel.org/pub/scm/linux/kernel/git/remoteproc/linux: (22 commits)
  dt-bindings: remoteproc: qcom,sdm845-adsp-pil: Fix qcom,halt-regs definition
  dt-bindings: remoteproc: qcom,sc7280-wpss-pil: Fix qcom,halt-regs definition
  dt-bindings: remoteproc: qcom,qcs404-cdsp-pil: Fix qcom,halt-regs definition
  dt-bindings: remoteproc: qcom,msm8996-mss-pil: allow glink-edge on msm8996
  dt-bindings: remoteproc: qcom,smd-edge: Mark qcom,ipc as deprecated
  remoteproc: k3-r5: Jump to error handling labels in start/stop errors
  remoteproc: mediatek: Fix error code in scp_rproc_init()
  remoteproc: k3-r5: Do not allow core1 to power up before core0 via sysfs
  remoteproc: k3-r5: Wait for core0 power-up before powering up core1
  remoteproc: mediatek: Add IMGSYS IPI command
  remoteproc: mediatek: Support setting DRAM and IPI shared buffer sizes
  remoteproc: mediatek: Support MT8188 SCP core 1
  dt-bindings: remoteproc: mediatek: Support MT8188 dual-core SCP
  drivers: remoteproc: xlnx: Fix uninitialized tcm mode
  drivers: remoteproc: xlnx: Fix uninitialized variable use
  drivers: remoteproc: xlnx: Add Versal and Versal-NET support
  remoteproc: zynqmp: parse TCM from device tree
  dt-bindings: remoteproc: Add Tightly Coupled Memory (TCM) bindings
  remoteproc: zynqmp: fix lockstep mode memory region
  remoteproc: zynqmp: Add coredump support
  ...
parents e66128fa 4d5ba6ea
...@@ -19,6 +19,7 @@ properties: ...@@ -19,6 +19,7 @@ properties:
- mediatek,mt8183-scp - mediatek,mt8183-scp
- mediatek,mt8186-scp - mediatek,mt8186-scp
- mediatek,mt8188-scp - mediatek,mt8188-scp
- mediatek,mt8188-scp-dual
- mediatek,mt8192-scp - mediatek,mt8192-scp
- mediatek,mt8195-scp - mediatek,mt8195-scp
- mediatek,mt8195-scp-dual - mediatek,mt8195-scp-dual
...@@ -194,6 +195,7 @@ allOf: ...@@ -194,6 +195,7 @@ allOf:
properties: properties:
compatible: compatible:
enum: enum:
- mediatek,mt8188-scp-dual
- mediatek,mt8195-scp-dual - mediatek,mt8195-scp-dual
then: then:
properties: properties:
......
...@@ -231,7 +231,6 @@ allOf: ...@@ -231,7 +231,6 @@ allOf:
- const: snoc_axi - const: snoc_axi
- const: mnoc_axi - const: mnoc_axi
- const: qdss - const: qdss
glink-edge: false
required: required:
- pll-supply - pll-supply
- smd-edge - smd-edge
......
...@@ -81,7 +81,11 @@ properties: ...@@ -81,7 +81,11 @@ properties:
$ref: /schemas/types.yaml#/definitions/phandle-array $ref: /schemas/types.yaml#/definitions/phandle-array
description: description:
Phandle reference to a syscon representing TCSR followed by the Phandle reference to a syscon representing TCSR followed by the
three offsets within syscon for q6, modem and nc halt registers. offset within syscon for q6 halt register.
items:
- items:
- description: phandle to TCSR syscon region
- description: offset to the Q6 halt register
qcom,smem-states: qcom,smem-states:
$ref: /schemas/types.yaml#/definitions/phandle-array $ref: /schemas/types.yaml#/definitions/phandle-array
......
...@@ -89,7 +89,11 @@ properties: ...@@ -89,7 +89,11 @@ properties:
$ref: /schemas/types.yaml#/definitions/phandle-array $ref: /schemas/types.yaml#/definitions/phandle-array
description: description:
Phandle reference to a syscon representing TCSR followed by the Phandle reference to a syscon representing TCSR followed by the
three offsets within syscon for q6, modem and nc halt registers. offset within syscon for q6 halt register.
items:
- items:
- description: phandle to TCSR syscon region
- description: offset to the Q6 halt register
qcom,qmp: qcom,qmp:
$ref: /schemas/types.yaml#/definitions/phandle $ref: /schemas/types.yaml#/definitions/phandle
......
...@@ -81,7 +81,11 @@ properties: ...@@ -81,7 +81,11 @@ properties:
$ref: /schemas/types.yaml#/definitions/phandle-array $ref: /schemas/types.yaml#/definitions/phandle-array
description: description:
Phandle reference to a syscon representing TCSR followed by the Phandle reference to a syscon representing TCSR followed by the
three offsets within syscon for q6, modem and nc halt registers. offset within syscon for q6 halt register.
items:
- items:
- description: phandle to TCSR syscon region
- description: offset to the Q6 halt register
qcom,smem-states: qcom,smem-states:
$ref: /schemas/types.yaml#/definitions/phandle-array $ref: /schemas/types.yaml#/definitions/phandle-array
......
...@@ -61,6 +61,7 @@ properties: ...@@ -61,6 +61,7 @@ properties:
description: description:
Three entries specifying the outgoing ipc bit used for signaling the Three entries specifying the outgoing ipc bit used for signaling the
remote processor. remote processor.
deprecated: true
qcom,smd-edge: qcom,smd-edge:
$ref: /schemas/types.yaml#/definitions/uint32 $ref: /schemas/types.yaml#/definitions/uint32
...@@ -111,7 +112,7 @@ examples: ...@@ -111,7 +112,7 @@ examples:
smd-edge { smd-edge {
interrupts = <GIC_SPI 156 IRQ_TYPE_EDGE_RISING>; interrupts = <GIC_SPI 156 IRQ_TYPE_EDGE_RISING>;
qcom,ipc = <&apcs 8 8>; mboxes = <&apcs 8>;
qcom,smd-edge = <1>; qcom,smd-edge = <1>;
}; };
}; };
...@@ -18,11 +18,26 @@ description: | ...@@ -18,11 +18,26 @@ description: |
properties: properties:
compatible: compatible:
const: xlnx,zynqmp-r5fss enum:
- xlnx,zynqmp-r5fss
- xlnx,versal-r5fss
- xlnx,versal-net-r52fss
"#address-cells":
const: 2
"#size-cells":
const: 2
ranges:
description: |
Standard ranges definition providing address translations for
local R5F TCM address spaces to bus addresses.
xlnx,cluster-mode: xlnx,cluster-mode:
$ref: /schemas/types.yaml#/definitions/uint32 $ref: /schemas/types.yaml#/definitions/uint32
enum: [0, 1, 2] enum: [0, 1, 2]
default: 1
description: | description: |
The RPU MPCore can operate in split mode (Dual-processor performance), Safety The RPU MPCore can operate in split mode (Dual-processor performance), Safety
lock-step mode(Both RPU cores execute the same code in lock-step, lock-step mode(Both RPU cores execute the same code in lock-step,
...@@ -36,8 +51,16 @@ properties: ...@@ -36,8 +51,16 @@ properties:
1: lockstep mode (default) 1: lockstep mode (default)
2: single cpu mode 2: single cpu mode
xlnx,tcm-mode:
$ref: /schemas/types.yaml#/definitions/uint32
enum: [0, 1]
description: |
Configure RPU TCM
0: split mode
1: lockstep mode
patternProperties: patternProperties:
"^r5f-[a-f0-9]+$": "^r(.*)@[0-9a-f]+$":
type: object type: object
description: | description: |
The RPU is located in the Low Power Domain of the Processor Subsystem. The RPU is located in the Low Power Domain of the Processor Subsystem.
...@@ -52,10 +75,22 @@ patternProperties: ...@@ -52,10 +75,22 @@ patternProperties:
properties: properties:
compatible: compatible:
const: xlnx,zynqmp-r5f enum:
- xlnx,zynqmp-r5f
- xlnx,versal-r5f
- xlnx,versal-net-r52f
reg:
minItems: 1
maxItems: 4
reg-names:
minItems: 1
maxItems: 4
power-domains: power-domains:
maxItems: 1 minItems: 2
maxItems: 5
mboxes: mboxes:
minItems: 1 minItems: 1
...@@ -101,35 +136,235 @@ patternProperties: ...@@ -101,35 +136,235 @@ patternProperties:
required: required:
- compatible - compatible
- reg
- reg-names
- power-domains - power-domains
unevaluatedProperties: false
required: required:
- compatible - compatible
- "#address-cells"
- "#size-cells"
- ranges
allOf:
- if:
properties:
compatible:
contains:
enum:
- xlnx,versal-net-r52fss
then:
properties:
xlnx,tcm-mode: false
patternProperties:
"^r52f@[0-9a-f]+$":
type: object
properties:
reg:
minItems: 1
items:
- description: ATCM internal memory
- description: BTCM internal memory
- description: CTCM internal memory
reg-names:
minItems: 1
items:
- const: atcm0
- const: btcm0
- const: ctcm0
power-domains:
minItems: 2
items:
- description: RPU core power domain
- description: ATCM power domain
- description: BTCM power domain
- description: CTCM power domain
- if:
properties:
compatible:
contains:
enum:
- xlnx,zynqmp-r5fss
- xlnx,versal-r5fss
then:
if:
properties:
xlnx,cluster-mode:
enum: [1, 2]
then:
properties:
xlnx,tcm-mode:
enum: [1]
patternProperties:
"^r5f@[0-9a-f]+$":
type: object
properties:
reg:
minItems: 1
items:
- description: ATCM internal memory
- description: BTCM internal memory
- description: extra ATCM memory in lockstep mode
- description: extra BTCM memory in lockstep mode
reg-names:
minItems: 1
items:
- const: atcm0
- const: btcm0
- const: atcm1
- const: btcm1
power-domains:
minItems: 2
items:
- description: RPU core power domain
- description: ATCM power domain
- description: BTCM power domain
- description: second ATCM power domain
- description: second BTCM power domain
required:
- xlnx,tcm-mode
else:
properties:
xlnx,tcm-mode:
enum: [0]
patternProperties:
"^r5f@[0-9a-f]+$":
type: object
properties:
reg:
minItems: 1
items:
- description: ATCM internal memory
- description: BTCM internal memory
reg-names:
minItems: 1
items:
- const: atcm0
- const: btcm0
power-domains:
minItems: 2
items:
- description: RPU core power domain
- description: ATCM power domain
- description: BTCM power domain
required:
- xlnx,tcm-mode
additionalProperties: false additionalProperties: false
examples: examples:
- | - |
remoteproc { #include <dt-bindings/power/xlnx-zynqmp-power.h>
compatible = "xlnx,zynqmp-r5fss";
xlnx,cluster-mode = <1>; // Split mode configuration
soc {
r5f-0 { #address-cells = <2>;
compatible = "xlnx,zynqmp-r5f"; #size-cells = <2>;
power-domains = <&zynqmp_firmware 0x7>;
memory-region = <&rproc_0_fw_image>, <&rpu0vdev0buffer>, <&rpu0vdev0vring0>, <&rpu0vdev0vring1>; remoteproc@ffe00000 {
mboxes = <&ipi_mailbox_rpu0 0>, <&ipi_mailbox_rpu0 1>; compatible = "xlnx,zynqmp-r5fss";
mbox-names = "tx", "rx"; xlnx,cluster-mode = <0>;
xlnx,tcm-mode = <0>;
#address-cells = <2>;
#size-cells = <2>;
ranges = <0x0 0x0 0x0 0xffe00000 0x0 0x10000>,
<0x0 0x20000 0x0 0xffe20000 0x0 0x10000>,
<0x1 0x0 0x0 0xffe90000 0x0 0x10000>,
<0x1 0x20000 0x0 0xffeb0000 0x0 0x10000>;
r5f@0 {
compatible = "xlnx,zynqmp-r5f";
reg = <0x0 0x0 0x0 0x10000>, <0x0 0x20000 0x0 0x10000>;
reg-names = "atcm0", "btcm0";
power-domains = <&zynqmp_firmware PD_RPU_0>,
<&zynqmp_firmware PD_R5_0_ATCM>,
<&zynqmp_firmware PD_R5_0_BTCM>;
memory-region = <&rproc_0_fw_image>, <&rpu0vdev0buffer>,
<&rpu0vdev0vring0>, <&rpu0vdev0vring1>;
mboxes = <&ipi_mailbox_rpu0 0>, <&ipi_mailbox_rpu0 1>;
mbox-names = "tx", "rx";
};
r5f@1 {
compatible = "xlnx,zynqmp-r5f";
reg = <0x1 0x0 0x0 0x10000>, <0x1 0x20000 0x0 0x10000>;
reg-names = "atcm0", "btcm0";
power-domains = <&zynqmp_firmware PD_RPU_1>,
<&zynqmp_firmware PD_R5_1_ATCM>,
<&zynqmp_firmware PD_R5_1_BTCM>;
memory-region = <&rproc_1_fw_image>, <&rpu1vdev0buffer>,
<&rpu1vdev0vring0>, <&rpu1vdev0vring1>;
mboxes = <&ipi_mailbox_rpu1 0>, <&ipi_mailbox_rpu1 1>;
mbox-names = "tx", "rx";
};
}; };
};
- |
//Lockstep configuration
soc {
#address-cells = <2>;
#size-cells = <2>;
remoteproc@ffe00000 {
compatible = "xlnx,zynqmp-r5fss";
xlnx,cluster-mode = <1>;
xlnx,tcm-mode = <1>;
#address-cells = <2>;
#size-cells = <2>;
ranges = <0x0 0x0 0x0 0xffe00000 0x0 0x10000>,
<0x0 0x20000 0x0 0xffe20000 0x0 0x10000>,
<0x0 0x10000 0x0 0xffe10000 0x0 0x10000>,
<0x0 0x30000 0x0 0xffe30000 0x0 0x10000>;
r5f@0 {
compatible = "xlnx,zynqmp-r5f";
reg = <0x0 0x0 0x0 0x10000>,
<0x0 0x20000 0x0 0x10000>,
<0x0 0x10000 0x0 0x10000>,
<0x0 0x30000 0x0 0x10000>;
reg-names = "atcm0", "btcm0", "atcm1", "btcm1";
power-domains = <&zynqmp_firmware PD_RPU_0>,
<&zynqmp_firmware PD_R5_0_ATCM>,
<&zynqmp_firmware PD_R5_0_BTCM>,
<&zynqmp_firmware PD_R5_1_ATCM>,
<&zynqmp_firmware PD_R5_1_BTCM>;
memory-region = <&rproc_0_fw_image>, <&rpu0vdev0buffer>,
<&rpu0vdev0vring0>, <&rpu0vdev0vring1>;
mboxes = <&ipi_mailbox_rpu0 0>, <&ipi_mailbox_rpu0 1>;
mbox-names = "tx", "rx";
};
r5f-1 { r5f@1 {
compatible = "xlnx,zynqmp-r5f"; compatible = "xlnx,zynqmp-r5f";
power-domains = <&zynqmp_firmware 0x8>; reg = <0x1 0x0 0x0 0x10000>, <0x1 0x20000 0x0 0x10000>;
memory-region = <&rproc_1_fw_image>, <&rpu1vdev0buffer>, <&rpu1vdev0vring0>, <&rpu1vdev0vring1>; reg-names = "atcm0", "btcm0";
mboxes = <&ipi_mailbox_rpu1 0>, <&ipi_mailbox_rpu1 1>; power-domains = <&zynqmp_firmware PD_RPU_1>,
mbox-names = "tx", "rx"; <&zynqmp_firmware PD_R5_1_ATCM>,
<&zynqmp_firmware PD_R5_1_BTCM>;
memory-region = <&rproc_1_fw_image>, <&rpu1vdev0buffer>,
<&rpu1vdev0vring0>, <&rpu1vdev0vring1>;
mboxes = <&ipi_mailbox_rpu1 0>, <&ipi_mailbox_rpu1 1>;
mbox-names = "tx", "rx";
};
}; };
}; };
... ...
...@@ -78,7 +78,6 @@ ...@@ -78,7 +78,6 @@
#define MT8195_L2TCM_OFFSET 0x850d0 #define MT8195_L2TCM_OFFSET 0x850d0
#define SCP_FW_VER_LEN 32 #define SCP_FW_VER_LEN 32
#define SCP_SHARE_BUFFER_SIZE 288
struct scp_run { struct scp_run {
u32 signaled; u32 signaled;
...@@ -97,6 +96,11 @@ struct scp_ipi_desc { ...@@ -97,6 +96,11 @@ struct scp_ipi_desc {
struct mtk_scp; struct mtk_scp;
struct mtk_scp_sizes_data {
size_t max_dram_size;
size_t ipi_share_buffer_size;
};
struct mtk_scp_of_data { struct mtk_scp_of_data {
int (*scp_clk_get)(struct mtk_scp *scp); int (*scp_clk_get)(struct mtk_scp *scp);
int (*scp_before_load)(struct mtk_scp *scp); int (*scp_before_load)(struct mtk_scp *scp);
...@@ -110,6 +114,7 @@ struct mtk_scp_of_data { ...@@ -110,6 +114,7 @@ struct mtk_scp_of_data {
u32 host_to_scp_int_bit; u32 host_to_scp_int_bit;
size_t ipi_buf_offset; size_t ipi_buf_offset;
const struct mtk_scp_sizes_data *scp_sizes;
}; };
struct mtk_scp_of_cluster { struct mtk_scp_of_cluster {
...@@ -141,10 +146,10 @@ struct mtk_scp { ...@@ -141,10 +146,10 @@ struct mtk_scp {
struct scp_ipi_desc ipi_desc[SCP_IPI_MAX]; struct scp_ipi_desc ipi_desc[SCP_IPI_MAX];
bool ipi_id_ack[SCP_IPI_MAX]; bool ipi_id_ack[SCP_IPI_MAX];
wait_queue_head_t ack_wq; wait_queue_head_t ack_wq;
u8 *share_buf;
void *cpu_addr; void *cpu_addr;
dma_addr_t dma_addr; dma_addr_t dma_addr;
size_t dram_size;
struct rproc_subdev *rpmsg_subdev; struct rproc_subdev *rpmsg_subdev;
...@@ -162,7 +167,7 @@ struct mtk_scp { ...@@ -162,7 +167,7 @@ struct mtk_scp {
struct mtk_share_obj { struct mtk_share_obj {
u32 id; u32 id;
u32 len; u32 len;
u8 share_buf[SCP_SHARE_BUFFER_SIZE]; u8 *share_buf;
}; };
void scp_memcpy_aligned(void __iomem *dst, const void *src, unsigned int len); void scp_memcpy_aligned(void __iomem *dst, const void *src, unsigned int len);
......
This diff is collapsed.
...@@ -162,10 +162,13 @@ int scp_ipi_send(struct mtk_scp *scp, u32 id, void *buf, unsigned int len, ...@@ -162,10 +162,13 @@ int scp_ipi_send(struct mtk_scp *scp, u32 id, void *buf, unsigned int len,
struct mtk_share_obj __iomem *send_obj = scp->send_buf; struct mtk_share_obj __iomem *send_obj = scp->send_buf;
u32 val; u32 val;
int ret; int ret;
const struct mtk_scp_sizes_data *scp_sizes;
scp_sizes = scp->data->scp_sizes;
if (WARN_ON(id <= SCP_IPI_INIT) || WARN_ON(id >= SCP_IPI_MAX) || if (WARN_ON(id <= SCP_IPI_INIT) || WARN_ON(id >= SCP_IPI_MAX) ||
WARN_ON(id == SCP_IPI_NS_SERVICE) || WARN_ON(id == SCP_IPI_NS_SERVICE) ||
WARN_ON(len > sizeof(send_obj->share_buf)) || WARN_ON(!buf)) WARN_ON(len > scp_sizes->ipi_share_buffer_size) || WARN_ON(!buf))
return -EINVAL; return -EINVAL;
ret = clk_prepare_enable(scp->clk); ret = clk_prepare_enable(scp->clk);
...@@ -184,7 +187,7 @@ int scp_ipi_send(struct mtk_scp *scp, u32 id, void *buf, unsigned int len, ...@@ -184,7 +187,7 @@ int scp_ipi_send(struct mtk_scp *scp, u32 id, void *buf, unsigned int len,
goto unlock_mutex; goto unlock_mutex;
} }
scp_memcpy_aligned(send_obj->share_buf, buf, len); scp_memcpy_aligned(&send_obj->share_buf, buf, len);
writel(len, &send_obj->len); writel(len, &send_obj->len);
writel(id, &send_obj->id); writel(id, &send_obj->id);
......
...@@ -72,7 +72,7 @@ void rproc_init_debugfs(void); ...@@ -72,7 +72,7 @@ void rproc_init_debugfs(void);
void rproc_exit_debugfs(void); void rproc_exit_debugfs(void);
/* from remoteproc_sysfs.c */ /* from remoteproc_sysfs.c */
extern struct class rproc_class; extern const struct class rproc_class;
int rproc_init_sysfs(void); int rproc_init_sysfs(void);
void rproc_exit_sysfs(void); void rproc_exit_sysfs(void);
......
...@@ -254,7 +254,7 @@ static const struct attribute_group *rproc_devgroups[] = { ...@@ -254,7 +254,7 @@ static const struct attribute_group *rproc_devgroups[] = {
NULL NULL
}; };
struct class rproc_class = { const struct class rproc_class = {
.name = "remoteproc", .name = "remoteproc",
.dev_groups = rproc_devgroups, .dev_groups = rproc_devgroups,
}; };
......
...@@ -103,12 +103,14 @@ struct k3_r5_soc_data { ...@@ -103,12 +103,14 @@ struct k3_r5_soc_data {
* @dev: cached device pointer * @dev: cached device pointer
* @mode: Mode to configure the Cluster - Split or LockStep * @mode: Mode to configure the Cluster - Split or LockStep
* @cores: list of R5 cores within the cluster * @cores: list of R5 cores within the cluster
* @core_transition: wait queue to sync core state changes
* @soc_data: SoC-specific feature data for a R5FSS * @soc_data: SoC-specific feature data for a R5FSS
*/ */
struct k3_r5_cluster { struct k3_r5_cluster {
struct device *dev; struct device *dev;
enum cluster_mode mode; enum cluster_mode mode;
struct list_head cores; struct list_head cores;
wait_queue_head_t core_transition;
const struct k3_r5_soc_data *soc_data; const struct k3_r5_soc_data *soc_data;
}; };
...@@ -128,6 +130,7 @@ struct k3_r5_cluster { ...@@ -128,6 +130,7 @@ struct k3_r5_cluster {
* @atcm_enable: flag to control ATCM enablement * @atcm_enable: flag to control ATCM enablement
* @btcm_enable: flag to control BTCM enablement * @btcm_enable: flag to control BTCM enablement
* @loczrama: flag to dictate which TCM is at device address 0x0 * @loczrama: flag to dictate which TCM is at device address 0x0
* @released_from_reset: flag to signal when core is out of reset
*/ */
struct k3_r5_core { struct k3_r5_core {
struct list_head elem; struct list_head elem;
...@@ -144,6 +147,7 @@ struct k3_r5_core { ...@@ -144,6 +147,7 @@ struct k3_r5_core {
u32 atcm_enable; u32 atcm_enable;
u32 btcm_enable; u32 btcm_enable;
u32 loczrama; u32 loczrama;
bool released_from_reset;
}; };
/** /**
...@@ -460,6 +464,8 @@ static int k3_r5_rproc_prepare(struct rproc *rproc) ...@@ -460,6 +464,8 @@ static int k3_r5_rproc_prepare(struct rproc *rproc)
ret); ret);
return ret; return ret;
} }
core->released_from_reset = true;
wake_up_interruptible(&cluster->core_transition);
/* /*
* Newer IP revisions like on J7200 SoCs support h/w auto-initialization * Newer IP revisions like on J7200 SoCs support h/w auto-initialization
...@@ -542,7 +548,7 @@ static int k3_r5_rproc_start(struct rproc *rproc) ...@@ -542,7 +548,7 @@ static int k3_r5_rproc_start(struct rproc *rproc)
struct k3_r5_rproc *kproc = rproc->priv; struct k3_r5_rproc *kproc = rproc->priv;
struct k3_r5_cluster *cluster = kproc->cluster; struct k3_r5_cluster *cluster = kproc->cluster;
struct device *dev = kproc->dev; struct device *dev = kproc->dev;
struct k3_r5_core *core; struct k3_r5_core *core0, *core;
u32 boot_addr; u32 boot_addr;
int ret; int ret;
...@@ -568,6 +574,16 @@ static int k3_r5_rproc_start(struct rproc *rproc) ...@@ -568,6 +574,16 @@ static int k3_r5_rproc_start(struct rproc *rproc)
goto unroll_core_run; goto unroll_core_run;
} }
} else { } else {
/* do not allow core 1 to start before core 0 */
core0 = list_first_entry(&cluster->cores, struct k3_r5_core,
elem);
if (core != core0 && core0->rproc->state == RPROC_OFFLINE) {
dev_err(dev, "%s: can not start core 1 before core 0\n",
__func__);
ret = -EPERM;
goto put_mbox;
}
ret = k3_r5_core_run(core); ret = k3_r5_core_run(core);
if (ret) if (ret)
goto put_mbox; goto put_mbox;
...@@ -613,7 +629,8 @@ static int k3_r5_rproc_stop(struct rproc *rproc) ...@@ -613,7 +629,8 @@ static int k3_r5_rproc_stop(struct rproc *rproc)
{ {
struct k3_r5_rproc *kproc = rproc->priv; struct k3_r5_rproc *kproc = rproc->priv;
struct k3_r5_cluster *cluster = kproc->cluster; struct k3_r5_cluster *cluster = kproc->cluster;
struct k3_r5_core *core = kproc->core; struct device *dev = kproc->dev;
struct k3_r5_core *core1, *core = kproc->core;
int ret; int ret;
/* halt all applicable cores */ /* halt all applicable cores */
...@@ -626,6 +643,16 @@ static int k3_r5_rproc_stop(struct rproc *rproc) ...@@ -626,6 +643,16 @@ static int k3_r5_rproc_stop(struct rproc *rproc)
} }
} }
} else { } else {
/* do not allow core 0 to stop before core 1 */
core1 = list_last_entry(&cluster->cores, struct k3_r5_core,
elem);
if (core != core1 && core1->rproc->state != RPROC_OFFLINE) {
dev_err(dev, "%s: can not stop core 0 before core 1\n",
__func__);
ret = -EPERM;
goto out;
}
ret = k3_r5_core_halt(core); ret = k3_r5_core_halt(core);
if (ret) if (ret)
goto out; goto out;
...@@ -1140,6 +1167,12 @@ static int k3_r5_rproc_configure_mode(struct k3_r5_rproc *kproc) ...@@ -1140,6 +1167,12 @@ static int k3_r5_rproc_configure_mode(struct k3_r5_rproc *kproc)
return ret; return ret;
} }
/*
* Skip the waiting mechanism for sequential power-on of cores if the
* core has already been booted by another entity.
*/
core->released_from_reset = c_state;
ret = ti_sci_proc_get_status(core->tsp, &boot_vec, &cfg, &ctrl, ret = ti_sci_proc_get_status(core->tsp, &boot_vec, &cfg, &ctrl,
&stat); &stat);
if (ret < 0) { if (ret < 0) {
...@@ -1280,6 +1313,26 @@ static int k3_r5_cluster_rproc_init(struct platform_device *pdev) ...@@ -1280,6 +1313,26 @@ static int k3_r5_cluster_rproc_init(struct platform_device *pdev)
cluster->mode == CLUSTER_MODE_SINGLECPU || cluster->mode == CLUSTER_MODE_SINGLECPU ||
cluster->mode == CLUSTER_MODE_SINGLECORE) cluster->mode == CLUSTER_MODE_SINGLECORE)
break; break;
/*
* R5 cores require to be powered on sequentially, core0
* should be in higher power state than core1 in a cluster
* So, wait for current core to power up before proceeding
* to next core and put timeout of 2sec for each core.
*
* This waiting mechanism is necessary because
* rproc_auto_boot_callback() for core1 can be called before
* core0 due to thread execution order.
*/
ret = wait_event_interruptible_timeout(cluster->core_transition,
core->released_from_reset,
msecs_to_jiffies(2000));
if (ret <= 0) {
dev_err(dev,
"Timed out waiting for %s core to power up!\n",
rproc->name);
return ret;
}
} }
return 0; return 0;
...@@ -1709,6 +1762,7 @@ static int k3_r5_probe(struct platform_device *pdev) ...@@ -1709,6 +1762,7 @@ static int k3_r5_probe(struct platform_device *pdev)
cluster->dev = dev; cluster->dev = dev;
cluster->soc_data = data; cluster->soc_data = data;
INIT_LIST_HEAD(&cluster->cores); INIT_LIST_HEAD(&cluster->cores);
init_waitqueue_head(&cluster->core_transition);
ret = of_property_read_u32(np, "ti,cluster-mode", &cluster->mode); ret = of_property_read_u32(np, "ti,cluster-mode", &cluster->mode);
if (ret < 0 && ret != -EINVAL) { if (ret < 0 && ret != -EINVAL) {
......
This diff is collapsed.
...@@ -43,6 +43,7 @@ enum scp_ipi_id { ...@@ -43,6 +43,7 @@ enum scp_ipi_id {
SCP_IPI_CROS_HOST_CMD, SCP_IPI_CROS_HOST_CMD,
SCP_IPI_VDEC_LAT, SCP_IPI_VDEC_LAT,
SCP_IPI_VDEC_CORE, SCP_IPI_VDEC_CORE,
SCP_IPI_IMGSYS_CMD,
SCP_IPI_NS_SERVICE = 0xFF, SCP_IPI_NS_SERVICE = 0xFF,
SCP_IPI_MAX = 0x100, SCP_IPI_MAX = 0x100,
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment