Merge 9cf5b508bd ("Merge tag 'rproc-v6.2' of git://git.kernel.org/pub/scm/linux/kernel/git/remoteproc/linux") into android-mainline
Steps on the way to 6.2-rc1 Change-Id: Id56a30e7b822a000cd1649167f11743550e60a27 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
@@ -22,6 +22,8 @@ properties:
|
||||
- fsl,imx8mn-cm7
|
||||
- fsl,imx8mp-cm7
|
||||
- fsl,imx8mq-cm4
|
||||
- fsl,imx8qm-cm4
|
||||
- fsl,imx8qxp-cm4
|
||||
- fsl,imx8ulp-cm33
|
||||
- fsl,imx93-cm33
|
||||
|
||||
@@ -54,12 +56,26 @@ properties:
|
||||
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
|
||||
|
||||
|
||||
@@ -0,0 +1,135 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only or BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/remoteproc/xlnx,zynqmp-r5fss.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Xilinx R5F processor subsystem
|
||||
|
||||
maintainers:
|
||||
- Ben Levinsky <ben.levinsky@amd.com>
|
||||
- Tanmay Shah <tanmay.shah@amd.com>
|
||||
|
||||
description: |
|
||||
The Xilinx platforms include a pair of Cortex-R5F processors (RPU) for
|
||||
real-time processing based on the Cortex-R5F processor core from ARM.
|
||||
The Cortex-R5F processor implements the Arm v7-R architecture and includes a
|
||||
floating-point unit that implements the Arm VFPv3 instruction set.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: xlnx,zynqmp-r5fss
|
||||
|
||||
xlnx,cluster-mode:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
enum: [0, 1, 2]
|
||||
description: |
|
||||
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,
|
||||
clock-for-clock) or Single CPU mode (RPU core 0 is held in reset while
|
||||
core 1 runs normally). The processor does not support dynamic configuration.
|
||||
Switching between modes is only permitted immediately after a processor reset.
|
||||
If set to 1 then lockstep mode and if 0 then split mode.
|
||||
If set to 2 then single CPU mode. When not defined, default will be lockstep mode.
|
||||
In summary,
|
||||
0: split mode
|
||||
1: lockstep mode (default)
|
||||
2: single cpu mode
|
||||
|
||||
patternProperties:
|
||||
"^r5f-[a-f0-9]+$":
|
||||
type: object
|
||||
description: |
|
||||
The RPU is located in the Low Power Domain of the Processor Subsystem.
|
||||
Each processor includes separate L1 instruction and data caches and
|
||||
tightly coupled memories (TCM). System memory is cacheable, but the TCM
|
||||
memory space is non-cacheable.
|
||||
|
||||
Each RPU contains one 64KB memory and two 32KB memories that
|
||||
are accessed via the TCM A and B port interfaces, for a total of 128KB
|
||||
per processor. In lock-step mode, the processor has access to 256KB of
|
||||
TCM memory.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: xlnx,zynqmp-r5f
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
mboxes:
|
||||
minItems: 1
|
||||
items:
|
||||
- description: mailbox channel to send data to RPU
|
||||
- description: mailbox channel to receive data from RPU
|
||||
|
||||
mbox-names:
|
||||
minItems: 1
|
||||
items:
|
||||
- const: tx
|
||||
- const: rx
|
||||
|
||||
sram:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle-array
|
||||
minItems: 1
|
||||
maxItems: 8
|
||||
items:
|
||||
maxItems: 1
|
||||
description: |
|
||||
phandles to one or more reserved on-chip SRAM regions. Other than TCM,
|
||||
the RPU can execute instructions and access data from the OCM memory,
|
||||
the main DDR memory, and other system memories.
|
||||
|
||||
The regions should be defined as child nodes of the respective SRAM
|
||||
node, and should be defined as per the generic bindings in
|
||||
Documentation/devicetree/bindings/sram/sram.yaml
|
||||
|
||||
memory-region:
|
||||
description: |
|
||||
List of phandles to the reserved memory regions associated with the
|
||||
remoteproc device. This is variable and describes the memories shared with
|
||||
the remote processor (e.g. remoteproc firmware and carveouts, rpmsg
|
||||
vrings, ...). This reserved memory region will be allocated in DDR memory.
|
||||
minItems: 1
|
||||
maxItems: 8
|
||||
items:
|
||||
- description: region used for RPU firmware image section
|
||||
- description: vdev buffer
|
||||
- description: vring0
|
||||
- description: vring1
|
||||
additionalItems: true
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- power-domains
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
remoteproc {
|
||||
compatible = "xlnx,zynqmp-r5fss";
|
||||
xlnx,cluster-mode = <1>;
|
||||
|
||||
r5f-0 {
|
||||
compatible = "xlnx,zynqmp-r5f";
|
||||
power-domains = <&zynqmp_firmware 0x7>;
|
||||
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";
|
||||
power-domains = <&zynqmp_firmware 0x8>;
|
||||
memory-region = <&rproc_1_fw_image>, <&rpu1vdev0buffer>, <&rpu1vdev0vring0>, <&rpu1vdev0vring1>;
|
||||
mboxes = <&ipi_mailbox_rpu1 0>, <&ipi_mailbox_rpu1 1>;
|
||||
mbox-names = "tx", "rx";
|
||||
};
|
||||
};
|
||||
...
|
||||
@@ -100,6 +100,22 @@
|
||||
};
|
||||
};
|
||||
|
||||
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>;
|
||||
@@ -203,6 +219,23 @@
|
||||
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>;
|
||||
|
||||
@@ -1166,6 +1166,103 @@ int zynqmp_pm_release_node(const u32 node)
|
||||
}
|
||||
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
|
||||
|
||||
@@ -352,6 +352,19 @@ config TI_K3_R5_REMOTEPROC
|
||||
It's safe to say N here if you're not interested in utilizing
|
||||
a slave processor.
|
||||
|
||||
config XLNX_R5_REMOTEPROC
|
||||
tristate "Xilinx R5 remoteproc support"
|
||||
depends on PM && ARCH_ZYNQMP
|
||||
select ZYNQMP_FIRMWARE
|
||||
select RPMSG_VIRTIO
|
||||
select MAILBOX
|
||||
select ZYNQMP_IPI_MBOX
|
||||
help
|
||||
Say y or m here to support Xilinx R5 remote processors via the remote
|
||||
processor framework.
|
||||
|
||||
It's safe to say N if not interested in using RPU r5f cores.
|
||||
|
||||
endif # REMOTEPROC
|
||||
|
||||
endmenu
|
||||
|
||||
@@ -38,3 +38,4 @@ obj-$(CONFIG_ST_SLIM_REMOTEPROC) += st_slim_rproc.o
|
||||
obj-$(CONFIG_STM32_RPROC) += stm32_rproc.o
|
||||
obj-$(CONFIG_TI_K3_DSP_REMOTEPROC) += ti_k3_dsp_remoteproc.o
|
||||
obj-$(CONFIG_TI_K3_R5_REMOTEPROC) += ti_k3_r5_remoteproc.o
|
||||
obj-$(CONFIG_XLNX_R5_REMOTEPROC) += xlnx_r5_remoteproc.o
|
||||
|
||||
@@ -347,9 +347,6 @@ static int imx_dsp_rproc_stop(struct rproc *rproc)
|
||||
struct device *dev = rproc->dev.parent;
|
||||
int ret = 0;
|
||||
|
||||
/* Make sure work is finished */
|
||||
flush_work(&priv->rproc_work);
|
||||
|
||||
if (rproc->state == RPROC_CRASHED) {
|
||||
priv->flags &= ~REMOTE_IS_READY;
|
||||
return 0;
|
||||
@@ -432,9 +429,18 @@ static void imx_dsp_rproc_vq_work(struct work_struct *work)
|
||||
{
|
||||
struct imx_dsp_rproc *priv = container_of(work, struct imx_dsp_rproc,
|
||||
rproc_work);
|
||||
struct rproc *rproc = priv->rproc;
|
||||
|
||||
mutex_lock(&rproc->lock);
|
||||
|
||||
if (rproc->state != RPROC_RUNNING)
|
||||
goto unlock_mutex;
|
||||
|
||||
rproc_vq_interrupt(priv->rproc, 0);
|
||||
rproc_vq_interrupt(priv->rproc, 1);
|
||||
|
||||
unlock_mutex:
|
||||
mutex_unlock(&rproc->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,9 +3,11 @@
|
||||
* Copyright (c) 2017 Pengutronix, Oleksij Rempel <kernel@pengutronix.de>
|
||||
*/
|
||||
|
||||
#include <dt-bindings/firmware/imx/rsrc.h>
|
||||
#include <linux/arm-smccc.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/firmware/imx/sci.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mailbox_client.h>
|
||||
@@ -15,6 +17,7 @@
|
||||
#include <linux/of_reserved_mem.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm_domain.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/remoteproc.h>
|
||||
#include <linux/workqueue.h>
|
||||
@@ -59,6 +62,8 @@
|
||||
#define IMX_SIP_RPROC_STARTED 0x01
|
||||
#define IMX_SIP_RPROC_STOP 0x02
|
||||
|
||||
#define IMX_SC_IRQ_GROUP_REBOOTED 5
|
||||
|
||||
/**
|
||||
* struct imx_rproc_mem - slim internal memory structure
|
||||
* @cpu_addr: MPU virtual address of the memory region
|
||||
@@ -71,10 +76,17 @@ struct imx_rproc_mem {
|
||||
size_t size;
|
||||
};
|
||||
|
||||
/* att flags */
|
||||
/* att flags: lower 16 bits specifying core, higher 16 bits for flags */
|
||||
/* M4 own area. Can be mapped at probe */
|
||||
#define ATT_OWN BIT(1)
|
||||
#define ATT_IOMEM BIT(2)
|
||||
#define ATT_OWN BIT(31)
|
||||
#define ATT_IOMEM BIT(30)
|
||||
|
||||
#define ATT_CORE_MASK 0xffff
|
||||
#define ATT_CORE(I) BIT((I))
|
||||
|
||||
static int imx_rproc_xtr_mbox_init(struct rproc *rproc);
|
||||
static void imx_rproc_free_mbox(struct rproc *rproc);
|
||||
static int imx_rproc_detach_pd(struct rproc *rproc);
|
||||
|
||||
struct imx_rproc {
|
||||
struct device *dev;
|
||||
@@ -89,6 +101,15 @@ struct imx_rproc {
|
||||
struct work_struct rproc_work;
|
||||
struct workqueue_struct *workqueue;
|
||||
void __iomem *rsc_table;
|
||||
struct imx_sc_ipc *ipc_handle;
|
||||
struct notifier_block rproc_nb;
|
||||
u32 rproc_pt; /* partition id */
|
||||
u32 rsrc_id; /* resource id */
|
||||
u32 entry; /* cpu start address */
|
||||
int num_pd;
|
||||
u32 core_index;
|
||||
struct device **pd_dev;
|
||||
struct device_link **pd_dev_link;
|
||||
};
|
||||
|
||||
static const struct imx_rproc_att imx_rproc_att_imx93[] = {
|
||||
@@ -113,8 +134,33 @@ static const struct imx_rproc_att imx_rproc_att_imx93[] = {
|
||||
{ 0x80000000, 0x80000000, 0x10000000, 0 },
|
||||
{ 0x90000000, 0x80000000, 0x10000000, 0 },
|
||||
|
||||
{ 0xC0000000, 0xa0000000, 0x10000000, 0 },
|
||||
{ 0xD0000000, 0xa0000000, 0x10000000, 0 },
|
||||
{ 0xC0000000, 0xC0000000, 0x10000000, 0 },
|
||||
{ 0xD0000000, 0xC0000000, 0x10000000, 0 },
|
||||
};
|
||||
|
||||
static const struct imx_rproc_att imx_rproc_att_imx8qm[] = {
|
||||
/* dev addr , sys addr , size , flags */
|
||||
{ 0x08000000, 0x08000000, 0x10000000, 0},
|
||||
/* TCML */
|
||||
{ 0x1FFE0000, 0x34FE0000, 0x00020000, ATT_OWN | ATT_IOMEM | ATT_CORE(0)},
|
||||
{ 0x1FFE0000, 0x38FE0000, 0x00020000, ATT_OWN | ATT_IOMEM | ATT_CORE(1)},
|
||||
/* TCMU */
|
||||
{ 0x20000000, 0x35000000, 0x00020000, ATT_OWN | ATT_IOMEM | ATT_CORE(0)},
|
||||
{ 0x20000000, 0x39000000, 0x00020000, ATT_OWN | ATT_IOMEM | ATT_CORE(1)},
|
||||
/* DDR (Data) */
|
||||
{ 0x80000000, 0x80000000, 0x60000000, 0 },
|
||||
};
|
||||
|
||||
static const struct imx_rproc_att imx_rproc_att_imx8qxp[] = {
|
||||
{ 0x08000000, 0x08000000, 0x10000000, 0 },
|
||||
/* TCML/U */
|
||||
{ 0x1FFE0000, 0x34FE0000, 0x00040000, ATT_OWN | ATT_IOMEM },
|
||||
/* OCRAM(Low 96KB) */
|
||||
{ 0x21000000, 0x00100000, 0x00018000, 0 },
|
||||
/* OCRAM */
|
||||
{ 0x21100000, 0x00100000, 0x00040000, 0 },
|
||||
/* DDR (Data) */
|
||||
{ 0x80000000, 0x80000000, 0x60000000, 0 },
|
||||
};
|
||||
|
||||
static const struct imx_rproc_att imx_rproc_att_imx8mn[] = {
|
||||
@@ -255,6 +301,18 @@ static const struct imx_rproc_dcfg imx_rproc_cfg_imx8mq = {
|
||||
.method = IMX_RPROC_MMIO,
|
||||
};
|
||||
|
||||
static const struct imx_rproc_dcfg imx_rproc_cfg_imx8qm = {
|
||||
.att = imx_rproc_att_imx8qm,
|
||||
.att_size = ARRAY_SIZE(imx_rproc_att_imx8qm),
|
||||
.method = IMX_RPROC_SCU_API,
|
||||
};
|
||||
|
||||
static const struct imx_rproc_dcfg imx_rproc_cfg_imx8qxp = {
|
||||
.att = imx_rproc_att_imx8qxp,
|
||||
.att_size = ARRAY_SIZE(imx_rproc_att_imx8qxp),
|
||||
.method = IMX_RPROC_SCU_API,
|
||||
};
|
||||
|
||||
static const struct imx_rproc_dcfg imx_rproc_cfg_imx8ulp = {
|
||||
.att = imx_rproc_att_imx8ulp,
|
||||
.att_size = ARRAY_SIZE(imx_rproc_att_imx8ulp),
|
||||
@@ -301,6 +359,10 @@ static int imx_rproc_start(struct rproc *rproc)
|
||||
struct arm_smccc_res res;
|
||||
int ret;
|
||||
|
||||
ret = imx_rproc_xtr_mbox_init(rproc);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
switch (dcfg->method) {
|
||||
case IMX_RPROC_MMIO:
|
||||
ret = regmap_update_bits(priv->regmap, dcfg->src_reg, dcfg->src_mask,
|
||||
@@ -310,6 +372,9 @@ static int imx_rproc_start(struct rproc *rproc)
|
||||
arm_smccc_smc(IMX_SIP_RPROC, IMX_SIP_RPROC_START, 0, 0, 0, 0, 0, 0, &res);
|
||||
ret = res.a0;
|
||||
break;
|
||||
case IMX_RPROC_SCU_API:
|
||||
ret = imx_sc_pm_cpu_start(priv->ipc_handle, priv->rsrc_id, true, priv->entry);
|
||||
break;
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
@@ -339,12 +404,17 @@ static int imx_rproc_stop(struct rproc *rproc)
|
||||
if (res.a1)
|
||||
dev_info(dev, "Not in wfi, force stopped\n");
|
||||
break;
|
||||
case IMX_RPROC_SCU_API:
|
||||
ret = imx_sc_pm_cpu_start(priv->ipc_handle, priv->rsrc_id, false, priv->entry);
|
||||
break;
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
if (ret)
|
||||
dev_err(dev, "Failed to stop remote core\n");
|
||||
else
|
||||
imx_rproc_free_mbox(rproc);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -359,6 +429,17 @@ static int imx_rproc_da_to_sys(struct imx_rproc *priv, u64 da,
|
||||
for (i = 0; i < dcfg->att_size; i++) {
|
||||
const struct imx_rproc_att *att = &dcfg->att[i];
|
||||
|
||||
/*
|
||||
* Ignore entries not belong to current core:
|
||||
* i.MX8QM has dual general M4_[0,1] cores, M4_0's own entries
|
||||
* has "ATT_CORE(0) & BIT(0)" true, M4_1's own entries has
|
||||
* "ATT_CORE(1) & BIT(1)" true.
|
||||
*/
|
||||
if (att->flags & ATT_CORE_MASK) {
|
||||
if (!((BIT(priv->core_index)) & (att->flags & ATT_CORE_MASK)))
|
||||
continue;
|
||||
}
|
||||
|
||||
if (da >= att->da && da + len < att->da + att->size) {
|
||||
unsigned int offset = da - att->da;
|
||||
|
||||
@@ -519,6 +600,22 @@ static void imx_rproc_kick(struct rproc *rproc, int vqid)
|
||||
|
||||
static int imx_rproc_attach(struct rproc *rproc)
|
||||
{
|
||||
return imx_rproc_xtr_mbox_init(rproc);
|
||||
}
|
||||
|
||||
static int imx_rproc_detach(struct rproc *rproc)
|
||||
{
|
||||
struct imx_rproc *priv = rproc->priv;
|
||||
const struct imx_rproc_dcfg *dcfg = priv->dcfg;
|
||||
|
||||
if (dcfg->method != IMX_RPROC_SCU_API)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (imx_sc_rm_is_resource_owned(priv->ipc_handle, priv->rsrc_id))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
imx_rproc_free_mbox(rproc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -537,6 +634,7 @@ static struct resource_table *imx_rproc_get_loaded_rsc_table(struct rproc *rproc
|
||||
static const struct rproc_ops imx_rproc_ops = {
|
||||
.prepare = imx_rproc_prepare,
|
||||
.attach = imx_rproc_attach,
|
||||
.detach = imx_rproc_detach,
|
||||
.start = imx_rproc_start,
|
||||
.stop = imx_rproc_stop,
|
||||
.kick = imx_rproc_kick,
|
||||
@@ -647,6 +745,18 @@ static int imx_rproc_xtr_mbox_init(struct rproc *rproc)
|
||||
struct device *dev = priv->dev;
|
||||
struct mbox_client *cl;
|
||||
|
||||
/*
|
||||
* stop() and detach() will free the mbox channels, so need
|
||||
* to request mbox channels in start() and attach().
|
||||
*
|
||||
* Because start() and attach() not able to handle mbox defer
|
||||
* probe, imx_rproc_xtr_mbox_init is also called in probe().
|
||||
* The check is to avoid request mbox again when start() or
|
||||
* attach() after probe() returns success.
|
||||
*/
|
||||
if (priv->tx_ch && priv->rx_ch)
|
||||
return 0;
|
||||
|
||||
if (!of_get_property(dev->of_node, "mbox-names", NULL))
|
||||
return 0;
|
||||
|
||||
@@ -676,8 +786,119 @@ static void imx_rproc_free_mbox(struct rproc *rproc)
|
||||
{
|
||||
struct imx_rproc *priv = rproc->priv;
|
||||
|
||||
mbox_free_channel(priv->tx_ch);
|
||||
mbox_free_channel(priv->rx_ch);
|
||||
if (priv->tx_ch) {
|
||||
mbox_free_channel(priv->tx_ch);
|
||||
priv->tx_ch = NULL;
|
||||
}
|
||||
|
||||
if (priv->rx_ch) {
|
||||
mbox_free_channel(priv->rx_ch);
|
||||
priv->rx_ch = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void imx_rproc_put_scu(struct rproc *rproc)
|
||||
{
|
||||
struct imx_rproc *priv = rproc->priv;
|
||||
const struct imx_rproc_dcfg *dcfg = priv->dcfg;
|
||||
|
||||
if (dcfg->method != IMX_RPROC_SCU_API)
|
||||
return;
|
||||
|
||||
if (imx_sc_rm_is_resource_owned(priv->ipc_handle, priv->rsrc_id)) {
|
||||
imx_rproc_detach_pd(rproc);
|
||||
return;
|
||||
}
|
||||
|
||||
imx_scu_irq_group_enable(IMX_SC_IRQ_GROUP_REBOOTED, BIT(priv->rproc_pt), false);
|
||||
imx_scu_irq_unregister_notifier(&priv->rproc_nb);
|
||||
}
|
||||
|
||||
static int imx_rproc_partition_notify(struct notifier_block *nb,
|
||||
unsigned long event, void *group)
|
||||
{
|
||||
struct imx_rproc *priv = container_of(nb, struct imx_rproc, rproc_nb);
|
||||
|
||||
/* Ignore other irqs */
|
||||
if (!((event & BIT(priv->rproc_pt)) && (*(u8 *)group == IMX_SC_IRQ_GROUP_REBOOTED)))
|
||||
return 0;
|
||||
|
||||
rproc_report_crash(priv->rproc, RPROC_WATCHDOG);
|
||||
|
||||
pr_info("Partition%d reset!\n", priv->rproc_pt);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int imx_rproc_attach_pd(struct imx_rproc *priv)
|
||||
{
|
||||
struct device *dev = priv->dev;
|
||||
int ret, i;
|
||||
|
||||
/*
|
||||
* If there is only one power-domain entry, the platform driver framework
|
||||
* will handle it, no need handle it in this driver.
|
||||
*/
|
||||
priv->num_pd = of_count_phandle_with_args(dev->of_node, "power-domains",
|
||||
"#power-domain-cells");
|
||||
if (priv->num_pd <= 1)
|
||||
return 0;
|
||||
|
||||
priv->pd_dev = devm_kmalloc_array(dev, priv->num_pd, sizeof(*priv->pd_dev), GFP_KERNEL);
|
||||
if (!priv->pd_dev)
|
||||
return -ENOMEM;
|
||||
|
||||
priv->pd_dev_link = devm_kmalloc_array(dev, priv->num_pd, sizeof(*priv->pd_dev_link),
|
||||
GFP_KERNEL);
|
||||
|
||||
if (!priv->pd_dev_link)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < priv->num_pd; i++) {
|
||||
priv->pd_dev[i] = dev_pm_domain_attach_by_id(dev, i);
|
||||
if (IS_ERR(priv->pd_dev[i])) {
|
||||
ret = PTR_ERR(priv->pd_dev[i]);
|
||||
goto detach_pd;
|
||||
}
|
||||
|
||||
priv->pd_dev_link[i] = device_link_add(dev, priv->pd_dev[i], DL_FLAG_STATELESS |
|
||||
DL_FLAG_PM_RUNTIME | DL_FLAG_RPM_ACTIVE);
|
||||
if (!priv->pd_dev_link[i]) {
|
||||
dev_pm_domain_detach(priv->pd_dev[i], false);
|
||||
ret = -EINVAL;
|
||||
goto detach_pd;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
detach_pd:
|
||||
while (--i >= 0) {
|
||||
device_link_del(priv->pd_dev_link[i]);
|
||||
dev_pm_domain_detach(priv->pd_dev[i], false);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int imx_rproc_detach_pd(struct rproc *rproc)
|
||||
{
|
||||
struct imx_rproc *priv = rproc->priv;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* If there is only one power-domain entry, the platform driver framework
|
||||
* will handle it, no need handle it in this driver.
|
||||
*/
|
||||
if (priv->num_pd <= 1)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < priv->num_pd; i++) {
|
||||
device_link_del(priv->pd_dev_link[i]);
|
||||
dev_pm_domain_detach(priv->pd_dev[i], false);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int imx_rproc_detect_mode(struct imx_rproc *priv)
|
||||
@@ -689,6 +910,7 @@ static int imx_rproc_detect_mode(struct imx_rproc *priv)
|
||||
struct arm_smccc_res res;
|
||||
int ret;
|
||||
u32 val;
|
||||
u8 pt;
|
||||
|
||||
switch (dcfg->method) {
|
||||
case IMX_RPROC_NONE:
|
||||
@@ -699,6 +921,61 @@ static int imx_rproc_detect_mode(struct imx_rproc *priv)
|
||||
if (res.a0)
|
||||
priv->rproc->state = RPROC_DETACHED;
|
||||
return 0;
|
||||
case IMX_RPROC_SCU_API:
|
||||
ret = imx_scu_get_handle(&priv->ipc_handle);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = of_property_read_u32(dev->of_node, "fsl,resource-id", &priv->rsrc_id);
|
||||
if (ret) {
|
||||
dev_err(dev, "No fsl,resource-id property\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (priv->rsrc_id == IMX_SC_R_M4_1_PID0)
|
||||
priv->core_index = 1;
|
||||
else
|
||||
priv->core_index = 0;
|
||||
|
||||
/*
|
||||
* If Mcore resource is not owned by Acore partition, It is kicked by ROM,
|
||||
* and Linux could only do IPC with Mcore and nothing else.
|
||||
*/
|
||||
if (imx_sc_rm_is_resource_owned(priv->ipc_handle, priv->rsrc_id)) {
|
||||
if (of_property_read_u32(dev->of_node, "fsl,entry-address", &priv->entry))
|
||||
return -EINVAL;
|
||||
|
||||
return imx_rproc_attach_pd(priv);
|
||||
}
|
||||
|
||||
priv->rproc->state = RPROC_DETACHED;
|
||||
priv->rproc->recovery_disabled = false;
|
||||
rproc_set_feature(priv->rproc, RPROC_FEAT_ATTACH_ON_RECOVERY);
|
||||
|
||||
/* Get partition id and enable irq in SCFW */
|
||||
ret = imx_sc_rm_get_resource_owner(priv->ipc_handle, priv->rsrc_id, &pt);
|
||||
if (ret) {
|
||||
dev_err(dev, "not able to get resource owner\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
priv->rproc_pt = pt;
|
||||
priv->rproc_nb.notifier_call = imx_rproc_partition_notify;
|
||||
|
||||
ret = imx_scu_irq_register_notifier(&priv->rproc_nb);
|
||||
if (ret) {
|
||||
dev_err(dev, "register scu notifier failed, %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = imx_scu_irq_group_enable(IMX_SC_IRQ_GROUP_REBOOTED, BIT(priv->rproc_pt),
|
||||
true);
|
||||
if (ret) {
|
||||
imx_scu_irq_unregister_notifier(&priv->rproc_nb);
|
||||
dev_err(dev, "Enable irq failed, %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -803,7 +1080,7 @@ static int imx_rproc_probe(struct platform_device *pdev)
|
||||
|
||||
ret = imx_rproc_clk_enable(priv);
|
||||
if (ret)
|
||||
goto err_put_mbox;
|
||||
goto err_put_scu;
|
||||
|
||||
INIT_WORK(&priv->rproc_work, imx_rproc_vq_work);
|
||||
|
||||
@@ -820,6 +1097,8 @@ static int imx_rproc_probe(struct platform_device *pdev)
|
||||
|
||||
err_put_clk:
|
||||
clk_disable_unprepare(priv->clk);
|
||||
err_put_scu:
|
||||
imx_rproc_put_scu(rproc);
|
||||
err_put_mbox:
|
||||
imx_rproc_free_mbox(rproc);
|
||||
err_put_wkq:
|
||||
@@ -837,6 +1116,7 @@ static int imx_rproc_remove(struct platform_device *pdev)
|
||||
|
||||
clk_disable_unprepare(priv->clk);
|
||||
rproc_del(rproc);
|
||||
imx_rproc_put_scu(rproc);
|
||||
imx_rproc_free_mbox(rproc);
|
||||
destroy_workqueue(priv->workqueue);
|
||||
rproc_free(rproc);
|
||||
@@ -852,6 +1132,8 @@ static const struct of_device_id imx_rproc_of_match[] = {
|
||||
{ .compatible = "fsl,imx8mm-cm4", .data = &imx_rproc_cfg_imx8mq },
|
||||
{ .compatible = "fsl,imx8mn-cm7", .data = &imx_rproc_cfg_imx8mn },
|
||||
{ .compatible = "fsl,imx8mp-cm7", .data = &imx_rproc_cfg_imx8mn },
|
||||
{ .compatible = "fsl,imx8qxp-cm4", .data = &imx_rproc_cfg_imx8qxp },
|
||||
{ .compatible = "fsl,imx8qm-cm4", .data = &imx_rproc_cfg_imx8qm },
|
||||
{ .compatible = "fsl,imx8ulp-cm33", .data = &imx_rproc_cfg_imx8ulp },
|
||||
{ .compatible = "fsl,imx93-cm33", .data = &imx_rproc_cfg_imx93 },
|
||||
{},
|
||||
|
||||
@@ -449,6 +449,7 @@ static int adsp_alloc_memory_region(struct qcom_adsp *adsp)
|
||||
}
|
||||
|
||||
ret = of_address_to_resource(node, 0, &r);
|
||||
of_node_put(node);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -556,6 +557,7 @@ static int adsp_probe(struct platform_device *pdev)
|
||||
detach_proxy_pds:
|
||||
adsp_pds_detach(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
|
||||
free_rproc:
|
||||
device_init_wakeup(adsp->dev, false);
|
||||
rproc_free(rproc);
|
||||
|
||||
return ret;
|
||||
@@ -572,6 +574,8 @@ static int adsp_remove(struct platform_device *pdev)
|
||||
qcom_remove_sysmon_subdev(adsp->sysmon);
|
||||
qcom_remove_smd_subdev(adsp->rproc, &adsp->smd_subdev);
|
||||
qcom_remove_ssr_subdev(adsp->rproc, &adsp->ssr_subdev);
|
||||
adsp_pds_detach(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
|
||||
device_init_wakeup(adsp->dev, false);
|
||||
rproc_free(adsp->rproc);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -351,7 +351,7 @@ static int q6v5_wcss_qcs404_power_on(struct q6v5_wcss *wcss)
|
||||
if (ret) {
|
||||
dev_err(wcss->dev,
|
||||
"xo cbcr enabling timed out (rc:%d)\n", ret);
|
||||
return ret;
|
||||
goto disable_xo_cbcr_clk;
|
||||
}
|
||||
|
||||
writel(0, wcss->reg_base + Q6SS_CGC_OVERRIDE);
|
||||
@@ -417,6 +417,7 @@ disable_sleep_cbcr_clk:
|
||||
val = readl(wcss->reg_base + Q6SS_SLEEP_CBCR);
|
||||
val &= ~Q6SS_CLK_ENABLE;
|
||||
writel(val, wcss->reg_base + Q6SS_SLEEP_CBCR);
|
||||
disable_xo_cbcr_clk:
|
||||
val = readl(wcss->reg_base + Q6SS_XO_CBCR);
|
||||
val &= ~Q6SS_CLK_ENABLE;
|
||||
writel(val, wcss->reg_base + Q6SS_XO_CBCR);
|
||||
@@ -827,6 +828,9 @@ static int q6v5_wcss_init_mmio(struct q6v5_wcss *wcss,
|
||||
int ret;
|
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "qdsp6");
|
||||
if (!res)
|
||||
return -EINVAL;
|
||||
|
||||
wcss->reg_base = devm_ioremap(&pdev->dev, res->start,
|
||||
resource_size(res));
|
||||
if (!wcss->reg_base)
|
||||
|
||||
@@ -190,7 +190,7 @@ struct ssctl_shutdown_resp {
|
||||
struct qmi_response_type_v01 resp;
|
||||
};
|
||||
|
||||
static struct qmi_elem_info ssctl_shutdown_resp_ei[] = {
|
||||
static const struct qmi_elem_info ssctl_shutdown_resp_ei[] = {
|
||||
{
|
||||
.data_type = QMI_STRUCT,
|
||||
.elem_len = 1,
|
||||
@@ -211,7 +211,7 @@ struct ssctl_subsys_event_req {
|
||||
u32 evt_driven;
|
||||
};
|
||||
|
||||
static struct qmi_elem_info ssctl_subsys_event_req_ei[] = {
|
||||
static const struct qmi_elem_info ssctl_subsys_event_req_ei[] = {
|
||||
{
|
||||
.data_type = QMI_DATA_LEN,
|
||||
.elem_len = 1,
|
||||
@@ -269,7 +269,7 @@ struct ssctl_subsys_event_resp {
|
||||
struct qmi_response_type_v01 resp;
|
||||
};
|
||||
|
||||
static struct qmi_elem_info ssctl_subsys_event_resp_ei[] = {
|
||||
static const struct qmi_elem_info ssctl_subsys_event_resp_ei[] = {
|
||||
{
|
||||
.data_type = QMI_STRUCT,
|
||||
.elem_len = 1,
|
||||
@@ -283,7 +283,7 @@ static struct qmi_elem_info ssctl_subsys_event_resp_ei[] = {
|
||||
{}
|
||||
};
|
||||
|
||||
static struct qmi_elem_info ssctl_shutdown_ind_ei[] = {
|
||||
static const struct qmi_elem_info ssctl_shutdown_ind_ei[] = {
|
||||
{}
|
||||
};
|
||||
|
||||
@@ -652,7 +652,9 @@ struct qcom_sysmon *qcom_add_sysmon_subdev(struct rproc *rproc,
|
||||
if (sysmon->shutdown_irq != -ENODATA) {
|
||||
dev_err(sysmon->dev,
|
||||
"failed to retrieve shutdown-ack IRQ\n");
|
||||
return ERR_PTR(sysmon->shutdown_irq);
|
||||
ret = sysmon->shutdown_irq;
|
||||
kfree(sysmon);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
} else {
|
||||
ret = devm_request_threaded_irq(sysmon->dev,
|
||||
@@ -663,6 +665,7 @@ struct qcom_sysmon *qcom_add_sysmon_subdev(struct rproc *rproc,
|
||||
if (ret) {
|
||||
dev_err(sysmon->dev,
|
||||
"failed to acquire shutdown-ack IRQ\n");
|
||||
kfree(sysmon);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -509,7 +509,13 @@ static int rproc_handle_vdev(struct rproc *rproc, void *ptr,
|
||||
rvdev_data.rsc_offset = offset;
|
||||
rvdev_data.rsc = rsc;
|
||||
|
||||
pdev = platform_device_register_data(dev, "rproc-virtio", rvdev_data.index, &rvdev_data,
|
||||
/*
|
||||
* When there is more than one remote processor, rproc->nb_vdev number is
|
||||
* same for each separate instances of "rproc". If rvdev_data.index is used
|
||||
* as device id, then we get duplication in sysfs, so need to use
|
||||
* PLATFORM_DEVID_AUTO to auto select device id.
|
||||
*/
|
||||
pdev = platform_device_register_data(dev, "rproc-virtio", PLATFORM_DEVID_AUTO, &rvdev_data,
|
||||
sizeof(rvdev_data));
|
||||
if (IS_ERR(pdev)) {
|
||||
dev_err(dev, "failed to create rproc-virtio device\n");
|
||||
@@ -1862,12 +1868,18 @@ static void rproc_crash_handler_work(struct work_struct *work)
|
||||
|
||||
mutex_lock(&rproc->lock);
|
||||
|
||||
if (rproc->state == RPROC_CRASHED || rproc->state == RPROC_OFFLINE) {
|
||||
if (rproc->state == RPROC_CRASHED) {
|
||||
/* handle only the first crash detected */
|
||||
mutex_unlock(&rproc->lock);
|
||||
return;
|
||||
}
|
||||
|
||||
if (rproc->state == RPROC_OFFLINE) {
|
||||
/* Don't recover if the remote processor was stopped */
|
||||
mutex_unlock(&rproc->lock);
|
||||
goto out;
|
||||
}
|
||||
|
||||
rproc->state = RPROC_CRASHED;
|
||||
dev_err(dev, "handling crash #%u in %s\n", ++rproc->crash_cnt,
|
||||
rproc->name);
|
||||
@@ -1877,6 +1889,7 @@ static void rproc_crash_handler_work(struct work_struct *work)
|
||||
if (!rproc->recovery_disabled)
|
||||
rproc_trigger_recovery(rproc);
|
||||
|
||||
out:
|
||||
pm_relax(rproc->dev.parent);
|
||||
}
|
||||
|
||||
@@ -2106,7 +2119,7 @@ struct rproc *rproc_get_by_phandle(phandle phandle)
|
||||
|
||||
rcu_read_lock();
|
||||
list_for_each_entry_rcu(r, &rproc_list, node) {
|
||||
if (r->dev.parent && r->dev.parent->of_node == np) {
|
||||
if (r->dev.parent && device_match_of_node(r->dev.parent, np)) {
|
||||
/* prevent underlying implementation from being removed */
|
||||
if (!try_module_get(r->dev.parent->driver->owner)) {
|
||||
dev_err(&r->dev, "can't get owner\n");
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -6,6 +6,12 @@
|
||||
#ifndef _DT_BINDINGS_ZYNQMP_POWER_H
|
||||
#define _DT_BINDINGS_ZYNQMP_POWER_H
|
||||
|
||||
#define PD_RPU_0 7
|
||||
#define PD_RPU_1 8
|
||||
#define PD_R5_0_ATCM 15
|
||||
#define PD_R5_0_BTCM 16
|
||||
#define PD_R5_1_ATCM 17
|
||||
#define PD_R5_1_BTCM 18
|
||||
#define PD_USB_0 22
|
||||
#define PD_USB_1 23
|
||||
#define PD_TTC_0 24
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
#ifndef __FIRMWARE_ZYNQMP_H__
|
||||
#define __FIRMWARE_ZYNQMP_H__
|
||||
#include <linux/types.h>
|
||||
|
||||
#include <linux/err.h>
|
||||
|
||||
@@ -87,6 +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,6 +138,10 @@ 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,
|
||||
@@ -176,6 +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,
|
||||
@@ -516,6 +538,15 @@ int zynqmp_pm_is_function_supported(const u32 api_id, const u32 id);
|
||||
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);
|
||||
@@ -795,6 +826,35 @@ static inline int zynqmp_pm_register_sgi(u32 sgi_num, u32 reset)
|
||||
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)
|
||||
|
||||
Reference in New Issue
Block a user