[U-Boot] [PATCH v3 0/9] arm: k3: Allow for exclusive and shared device requests

Sysfw provides an option for requesting exclusive access for a device using the flags MSG_FLAG_DEVICE_EXCLUSIVE. If this flag is not used, the device is meant to be shared across hosts. Once a device is requested from a host with this flag set, any request to this device from a different host will be nacked by sysfw.
Current tisci firmware and pm drivers always requests for device with exclusive permissions set. But this is not be true for certain devices that are expcted to be shared across different host contexts. So add support for getting the shared or exclusive permissions from DT and request firmware accordingly.
Same bindings are acked in kernel: https://patchwork.kernel.org/project/linux-arm-kernel/list/?series=103447
Also this series adds support for shutting down cores so that R5 cores can be shutdown right after jumping to ATF.
Changes since v2: - Added support for releasing exclusive devices before shutdown - Rebased on top of AM65x EEPROM support: https://patchwork.ozlabs.org/project/uboot/list/?series=111847
Andreas Dannenberg (2): firmware: ti_sci: Add processor shutdown API method armv7R: K3: am654: Shut down R5 core after ATF startup on A53
Lokesh Vutla (7): firmware: ti_sci: Allow for device shared and exclusive requests firmware: ti_sci: Add a command for releasing all exclusive devices armv7R: k3: Release all the exclusive devices power-domain: Add private data to power domain dt-bindings: ti_sci_pm_domains: Add support for exclusive and shared access power: domain: ti_sci_power_domains: Add support for exclusive and shared access arm: dts: k3-am654: Update power-domains property for each node
arch/arm/dts/k3-am65-main.dtsi | 10 +- arch/arm/dts/k3-am65-mcu.dtsi | 2 +- arch/arm/dts/k3-am65-wakeup.dtsi | 4 +- arch/arm/dts/k3-am65.dtsi | 1 + arch/arm/dts/k3-am654-base-board-u-boot.dtsi | 2 +- arch/arm/dts/k3-am654-ddr.dtsi | 4 +- arch/arm/dts/k3-am654-r5-base-board.dts | 8 +- arch/arm/mach-k3/am6_init.c | 62 ++++ arch/arm/mach-k3/common.c | 10 +- arch/arm/mach-k3/include/mach/sys_proto.h | 2 +- .../power/ti,sci-pm-domain.txt | 11 +- drivers/firmware/ti_sci.c | 291 +++++++++++++++++- drivers/firmware/ti_sci.h | 50 +++ drivers/power/domain/ti-sci-power-domain.c | 31 +- include/dt-bindings/soc/ti,sci_pm_domain.h | 9 + include/linux/soc/ti/ti_sci_protocol.h | 11 + include/power-domain.h | 15 +- 17 files changed, 483 insertions(+), 40 deletions(-) create mode 100644 include/dt-bindings/soc/ti,sci_pm_domain.h

Sysfw provides an option for requesting exclusive access for a device using the flags MSG_FLAG_DEVICE_EXCLUSIVE. If this flag is not used, the device is meant to be shared across hosts. Once a device is requested from a host with this flag set, any request to this device from a different host will be nacked by sysfw. Current tisci driver enables this flag for every device requests. But this may not be true for all the devices. So provide a separate commands in driver for exclusive and shared device requests.
Signed-off-by: Lokesh Vutla lokeshvutla@ti.com --- drivers/firmware/ti_sci.c | 25 ++++++++++++++++++++----- include/linux/soc/ti/ti_sci_protocol.h | 3 +++ 2 files changed, 23 insertions(+), 5 deletions(-)
diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c index 303aa6a631..eadb91e107 100644 --- a/drivers/firmware/ti_sci.c +++ b/drivers/firmware/ti_sci.c @@ -547,8 +547,14 @@ static int ti_sci_get_device_state(const struct ti_sci_handle *handle, */ static int ti_sci_cmd_get_device(const struct ti_sci_handle *handle, u32 id) { - return ti_sci_set_device_state(handle, id, - MSG_FLAG_DEVICE_EXCLUSIVE, + return ti_sci_set_device_state(handle, id, 0, + MSG_DEVICE_SW_STATE_ON); +} + +static int ti_sci_cmd_get_device_exclusive(const struct ti_sci_handle *handle, + u32 id) +{ + return ti_sci_set_device_state(handle, id, MSG_FLAG_DEVICE_EXCLUSIVE, MSG_DEVICE_SW_STATE_ON); }
@@ -566,7 +572,14 @@ static int ti_sci_cmd_get_device(const struct ti_sci_handle *handle, u32 id) static int ti_sci_cmd_idle_device(const struct ti_sci_handle *handle, u32 id) { return ti_sci_set_device_state(handle, id, - MSG_FLAG_DEVICE_EXCLUSIVE, + 0, + MSG_DEVICE_SW_STATE_RETENTION); +} + +static int ti_sci_cmd_idle_device_exclusive(const struct ti_sci_handle *handle, + u32 id) +{ + return ti_sci_set_device_state(handle, id, MSG_FLAG_DEVICE_EXCLUSIVE, MSG_DEVICE_SW_STATE_RETENTION); }
@@ -583,8 +596,8 @@ static int ti_sci_cmd_idle_device(const struct ti_sci_handle *handle, u32 id) */ static int ti_sci_cmd_put_device(const struct ti_sci_handle *handle, u32 id) { - return ti_sci_set_device_state(handle, id, - 0, MSG_DEVICE_SW_STATE_AUTO_OFF); + return ti_sci_set_device_state(handle, id, 0, + MSG_DEVICE_SW_STATE_AUTO_OFF); }
/** @@ -2632,7 +2645,9 @@ static void ti_sci_setup_ops(struct ti_sci_info *info) bops->board_config_pm = ti_sci_cmd_set_board_config_pm;
dops->get_device = ti_sci_cmd_get_device; + dops->get_device_exclusive = ti_sci_cmd_get_device_exclusive; dops->idle_device = ti_sci_cmd_idle_device; + dops->idle_device_exclusive = ti_sci_cmd_idle_device_exclusive; dops->put_device = ti_sci_cmd_put_device; dops->is_valid = ti_sci_cmd_dev_is_valid; dops->get_context_loss_count = ti_sci_cmd_dev_get_clcnt; diff --git a/include/linux/soc/ti/ti_sci_protocol.h b/include/linux/soc/ti/ti_sci_protocol.h index c57802f293..842fb596f7 100644 --- a/include/linux/soc/ti/ti_sci_protocol.h +++ b/include/linux/soc/ti/ti_sci_protocol.h @@ -117,7 +117,10 @@ struct ti_sci_board_ops { */ struct ti_sci_dev_ops { int (*get_device)(const struct ti_sci_handle *handle, u32 id); + int (*get_device_exclusive)(const struct ti_sci_handle *handle, u32 id); int (*idle_device)(const struct ti_sci_handle *handle, u32 id); + int (*idle_device_exclusive)(const struct ti_sci_handle *handle, + u32 id); int (*put_device)(const struct ti_sci_handle *handle, u32 id); int (*is_valid)(const struct ti_sci_handle *handle, u32 id); int (*get_context_loss_count)(const struct ti_sci_handle *handle,

On Fri, Jun 07, 2019 at 07:24:39PM +0530, Lokesh Vutla wrote:
Sysfw provides an option for requesting exclusive access for a device using the flags MSG_FLAG_DEVICE_EXCLUSIVE. If this flag is not used, the device is meant to be shared across hosts. Once a device is requested from a host with this flag set, any request to this device from a different host will be nacked by sysfw. Current tisci driver enables this flag for every device requests. But this may not be true for all the devices. So provide a separate commands in driver for exclusive and shared device requests.
Signed-off-by: Lokesh Vutla lokeshvutla@ti.com
Applied to u-boot/master, thanks!

From: Andreas Dannenberg dannenberg@ti.com
Add and expose a new processor shutdown API that wraps the two TISCI messages involved in initiating a core shutdown. The API will first queue a message to have the DMSC wait for a certain processor boot status to happen followed by a message to trigger the actual shutdown- with both messages being sent without waiting or requesting for a response. Note that the processor shutdown API call will need to be followed up by user software placing the respective core into either WFE or WFI mode.
Signed-off-by: Andreas Dannenberg dannenberg@ti.com --- drivers/firmware/ti_sci.c | 191 ++++++++++++++++++++++++- drivers/firmware/ti_sci.h | 50 +++++++ include/linux/soc/ti/ti_sci_protocol.h | 4 + 3 files changed, 241 insertions(+), 4 deletions(-)
diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c index eadb91e107..8c68f98788 100644 --- a/drivers/firmware/ti_sci.c +++ b/drivers/firmware/ti_sci.c @@ -101,7 +101,8 @@ struct ti_sci_info { * @msg_flags: Flag to set for the message * @buf: Buffer to be send to mailbox channel * @tx_message_size: transmit message size - * @rx_message_size: receive message size + * @rx_message_size: receive message size. may be set to zero for send-only + * transactions. * * Helper function which is used by various command functions that are * exposed to clients of this driver for allocating a message traffic event. @@ -121,7 +122,8 @@ static struct ti_sci_xfer *ti_sci_setup_one_xfer(struct ti_sci_info *info, /* Ensure we have sane transfer sizes */ if (rx_message_size > info->desc->max_msg_size || tx_message_size > info->desc->max_msg_size || - rx_message_size < sizeof(*hdr) || tx_message_size < sizeof(*hdr)) + (rx_message_size > 0 && rx_message_size < sizeof(*hdr)) || + tx_message_size < sizeof(*hdr)) return ERR_PTR(-ERANGE);
info->seq = ~info->seq; @@ -219,7 +221,9 @@ static inline int ti_sci_do_xfer(struct ti_sci_info *info,
xfer->tx_message.buf = (u32 *)secure_buf; xfer->tx_message.len += sizeof(secure_hdr); - xfer->rx_len += sizeof(secure_hdr); + + if (xfer->rx_len) + xfer->rx_len += sizeof(secure_hdr); }
/* Send the message */ @@ -230,7 +234,11 @@ static inline int ti_sci_do_xfer(struct ti_sci_info *info, return ret; }
- return ti_sci_get_response(info, xfer, &info->chan_rx); + /* Get response if requested */ + if (xfer->rx_len) + ret = ti_sci_get_response(info, xfer, &info->chan_rx); + + return ret; }
/** @@ -469,6 +477,49 @@ static int ti_sci_set_device_state(const struct ti_sci_handle *handle, return ret; }
+/** + * ti_sci_set_device_state_no_wait() - Set device state helper without + * requesting or waiting for a response. + * @handle: pointer to TI SCI handle + * @id: Device identifier + * @flags: flags to setup for the device + * @state: State to move the device to + * + * Return: 0 if all went well, else returns appropriate error value. + */ +static int ti_sci_set_device_state_no_wait(const struct ti_sci_handle *handle, + u32 id, u32 flags, u8 state) +{ + struct ti_sci_msg_req_set_device_state req; + struct ti_sci_info *info; + struct ti_sci_xfer *xfer; + int ret = 0; + + if (IS_ERR(handle)) + return PTR_ERR(handle); + if (!handle) + return -EINVAL; + + info = handle_to_ti_sci_info(handle); + + xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_SET_DEVICE_STATE, + flags | TI_SCI_FLAG_REQ_GENERIC_NORESPONSE, + (u32 *)&req, sizeof(req), 0); + if (IS_ERR(xfer)) { + ret = PTR_ERR(xfer); + dev_err(info->dev, "Message alloc failed(%d)\n", ret); + return ret; + } + req.id = id; + req.state = state; + + ret = ti_sci_do_xfer(info, xfer); + if (ret) + dev_err(info->dev, "Mbox send fail %d\n", ret); + + return ret; +} + /** * ti_sci_get_device_state() - Get device state helper * @handle: Handle to the device @@ -2039,6 +2090,137 @@ static int ti_sci_cmd_get_proc_boot_status(const struct ti_sci_handle *handle, return ret; }
+/** + * ti_sci_proc_wait_boot_status_no_wait() - Helper function to wait for a + * processor boot status without requesting or + * waiting for a response. + * @proc_id: Processor ID this request is for + * @num_wait_iterations: Total number of iterations we will check before + * we will timeout and give up + * @num_match_iterations: How many iterations should we have continued + * status to account for status bits glitching. + * This is to make sure that match occurs for + * consecutive checks. This implies that the + * worst case should consider that the stable + * time should at the worst be num_wait_iterations + * num_match_iterations to prevent timeout. + * @delay_per_iteration_us: Specifies how long to wait (in micro seconds) + * between each status checks. This is the minimum + * duration, and overhead of register reads and + * checks are on top of this and can vary based on + * varied conditions. + * @delay_before_iterations_us: Specifies how long to wait (in micro seconds) + * before the very first check in the first + * iteration of status check loop. This is the + * minimum duration, and overhead of register + * reads and checks are. + * @status_flags_1_set_all_wait:If non-zero, Specifies that all bits of the + * status matching this field requested MUST be 1. + * @status_flags_1_set_any_wait:If non-zero, Specifies that at least one of the + * bits matching this field requested MUST be 1. + * @status_flags_1_clr_all_wait:If non-zero, Specifies that all bits of the + * status matching this field requested MUST be 0. + * @status_flags_1_clr_any_wait:If non-zero, Specifies that at least one of the + * bits matching this field requested MUST be 0. + * + * Return: 0 if all goes well, else appropriate error message + */ +static int +ti_sci_proc_wait_boot_status_no_wait(const struct ti_sci_handle *handle, + u8 proc_id, + u8 num_wait_iterations, + u8 num_match_iterations, + u8 delay_per_iteration_us, + u8 delay_before_iterations_us, + u32 status_flags_1_set_all_wait, + u32 status_flags_1_set_any_wait, + u32 status_flags_1_clr_all_wait, + u32 status_flags_1_clr_any_wait) +{ + struct ti_sci_msg_req_wait_proc_boot_status req; + struct ti_sci_info *info; + struct ti_sci_xfer *xfer; + int ret = 0; + + if (IS_ERR(handle)) + return PTR_ERR(handle); + if (!handle) + return -EINVAL; + + info = handle_to_ti_sci_info(handle); + + xfer = ti_sci_setup_one_xfer(info, TISCI_MSG_WAIT_PROC_BOOT_STATUS, + TI_SCI_FLAG_REQ_GENERIC_NORESPONSE, + (u32 *)&req, sizeof(req), 0); + if (IS_ERR(xfer)) { + ret = PTR_ERR(xfer); + dev_err(info->dev, "Message alloc failed(%d)\n", ret); + return ret; + } + req.processor_id = proc_id; + req.num_wait_iterations = num_wait_iterations; + req.num_match_iterations = num_match_iterations; + req.delay_per_iteration_us = delay_per_iteration_us; + req.delay_before_iterations_us = delay_before_iterations_us; + req.status_flags_1_set_all_wait = status_flags_1_set_all_wait; + req.status_flags_1_set_any_wait = status_flags_1_set_any_wait; + req.status_flags_1_clr_all_wait = status_flags_1_clr_all_wait; + req.status_flags_1_clr_any_wait = status_flags_1_clr_any_wait; + + ret = ti_sci_do_xfer(info, xfer); + if (ret) + dev_err(info->dev, "Mbox send fail %d\n", ret); + + return ret; +} + +/** + * ti_sci_cmd_proc_shutdown_no_wait() - Command to shutdown a core without + * requesting or waiting for a response. Note that this API call + * should be followed by placing the respective processor into + * either WFE or WFI mode. + * @handle: Pointer to TI SCI handle + * @proc_id: Processor ID this request is for + * + * Return: 0 if all went well, else returns appropriate error value. + */ +static int ti_sci_cmd_proc_shutdown_no_wait(const struct ti_sci_handle *handle, + u8 proc_id) +{ + int ret; + + /* + * Send the core boot status wait message waiting for either WFE or + * WFI without requesting or waiting for a TISCI response with the + * maximum wait time to give us the best chance to get to the WFE/WFI + * command that should follow the invocation of this API before the + * DMSC-internal processing of this command times out. Note that + * waiting for the R5 WFE/WFI flags will also work on an ARMV8 type + * core as the related flag bit positions are the same. + */ + ret = ti_sci_proc_wait_boot_status_no_wait(handle, proc_id, + U8_MAX, 100, U8_MAX, U8_MAX, + 0, PROC_BOOT_STATUS_FLAG_R5_WFE | PROC_BOOT_STATUS_FLAG_R5_WFI, + 0, 0); + if (ret) { + dev_err(info->dev, "Sending core %u wait message fail %d\n", + proc_id, ret); + return ret; + } + + /* + * Release a processor managed by TISCI without requesting or waiting + * for a response. + */ + ret = ti_sci_set_device_state_no_wait(handle, proc_id, 0, + MSG_DEVICE_SW_STATE_AUTO_OFF); + if (ret) + dev_err(info->dev, "Sending core %u shutdown message fail %d\n", + proc_id, ret); + + return ret; +} + /** * ti_sci_cmd_ring_config() - configure RA ring * @handle: pointer to TI SCI handle @@ -2687,6 +2869,7 @@ static void ti_sci_setup_ops(struct ti_sci_info *info) pops->set_proc_boot_ctrl = ti_sci_cmd_set_proc_boot_ctrl; pops->proc_auth_boot_image = ti_sci_cmd_proc_auth_boot_image; pops->get_proc_boot_status = ti_sci_cmd_get_proc_boot_status; + pops->proc_shutdown_no_wait = ti_sci_cmd_proc_shutdown_no_wait;
rops->config = ti_sci_cmd_ring_config; rops->get_config = ti_sci_cmd_ring_get_config; diff --git a/drivers/firmware/ti_sci.h b/drivers/firmware/ti_sci.h index a484b1fa40..69ff74d6a9 100644 --- a/drivers/firmware/ti_sci.h +++ b/drivers/firmware/ti_sci.h @@ -50,6 +50,7 @@ #define TISCI_MSG_SET_PROC_BOOT_CTRL 0xc101 #define TISCI_MSG_PROC_AUTH_BOOT_IMIAGE 0xc120 #define TISCI_MSG_GET_PROC_BOOT_STATUS 0xc400 +#define TISCI_MSG_WAIT_PROC_BOOT_STATUS 0xc401
/* Resource Management Requests */ #define TI_SCI_MSG_GET_RESOURCE_RANGE 0x1500 @@ -772,6 +773,55 @@ struct ti_sci_msg_resp_get_proc_boot_status { u32 status_flags; } __packed;
+/** + * struct ti_sci_msg_req_wait_proc_boot_status - Wait for a processor + * boot status + * @hdr: Generic Header + * @processor_id: ID of processor + * @num_wait_iterations: Total number of iterations we will check before + * we will timeout and give up + * @num_match_iterations: How many iterations should we have continued + * status to account for status bits glitching. + * This is to make sure that match occurs for + * consecutive checks. This implies that the + * worst case should consider that the stable + * time should at the worst be num_wait_iterations + * num_match_iterations to prevent timeout. + * @delay_per_iteration_us: Specifies how long to wait (in micro seconds) + * between each status checks. This is the minimum + * duration, and overhead of register reads and + * checks are on top of this and can vary based on + * varied conditions. + * @delay_before_iterations_us: Specifies how long to wait (in micro seconds) + * before the very first check in the first + * iteration of status check loop. This is the + * minimum duration, and overhead of register + * reads and checks are. + * @status_flags_1_set_all_wait:If non-zero, Specifies that all bits of the + * status matching this field requested MUST be 1. + * @status_flags_1_set_any_wait:If non-zero, Specifies that at least one of the + * bits matching this field requested MUST be 1. + * @status_flags_1_clr_all_wait:If non-zero, Specifies that all bits of the + * status matching this field requested MUST be 0. + * @status_flags_1_clr_any_wait:If non-zero, Specifies that at least one of the + * bits matching this field requested MUST be 0. + * + * Request type is TISCI_MSG_WAIT_PROC_BOOT_STATUS, response is appropriate + * message, or NACK in case of inability to satisfy request. + */ +struct ti_sci_msg_req_wait_proc_boot_status { + struct ti_sci_msg_hdr hdr; + u8 processor_id; + u8 num_wait_iterations; + u8 num_match_iterations; + u8 delay_per_iteration_us; + u8 delay_before_iterations_us; + u32 status_flags_1_set_all_wait; + u32 status_flags_1_set_any_wait; + u32 status_flags_1_clr_all_wait; + u32 status_flags_1_clr_any_wait; +} __packed; + /** * struct ti_sci_msg_rm_ring_cfg_req - Configure a Navigator Subsystem ring * diff --git a/include/linux/soc/ti/ti_sci_protocol.h b/include/linux/soc/ti/ti_sci_protocol.h index 842fb596f7..cd6e5853b4 100644 --- a/include/linux/soc/ti/ti_sci_protocol.h +++ b/include/linux/soc/ti/ti_sci_protocol.h @@ -266,6 +266,8 @@ struct ti_sci_core_ops { * @set_proc_boot_ctrl: Setup limited control flags in specific cases. * @proc_auth_boot_image: * @get_proc_boot_status: Get the state of physical processor + * @proc_shutdown_no_wait: Shutdown a core without requesting or waiting for a + * response. * * NOTE: for all these functions, the following parameters are generic in * nature: @@ -287,6 +289,8 @@ struct ti_sci_proc_ops { int (*get_proc_boot_status)(const struct ti_sci_handle *handle, u8 pid, u64 *bv, u32 *cfg_flags, u32 *ctrl_flags, u32 *sts_flags); + int (*proc_shutdown_no_wait)(const struct ti_sci_handle *handle, + u8 pid); };
#define TI_SCI_RING_MODE_RING (0)

On Fri, Jun 07, 2019 at 07:24:40PM +0530, Lokesh Vutla wrote:
From: Andreas Dannenberg dannenberg@ti.com
Add and expose a new processor shutdown API that wraps the two TISCI messages involved in initiating a core shutdown. The API will first queue a message to have the DMSC wait for a certain processor boot status to happen followed by a message to trigger the actual shutdown- with both messages being sent without waiting or requesting for a response. Note that the processor shutdown API call will need to be followed up by user software placing the respective core into either WFE or WFI mode.
Signed-off-by: Andreas Dannenberg dannenberg@ti.com
Applied to u-boot/master, thanks!

Any host while requesting for a device can request for its exclusive access. If an exclusive permission is obtained then it is the host's responsibility to release the device before the software entity on the host completes its execution. Else any other host's request for the device will be nacked. So add a command that releases all the exclusive devices that is acquired by the current host. This should be used with utmost care and can be called only at the end of the execution.
Signed-off-by: Lokesh Vutla lokeshvutla@ti.com --- drivers/firmware/ti_sci.c | 75 ++++++++++++++++++++++++++ include/linux/soc/ti/ti_sci_protocol.h | 4 ++ 2 files changed, 79 insertions(+)
diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c index 8c68f98788..1fd29f2cdf 100644 --- a/drivers/firmware/ti_sci.c +++ b/drivers/firmware/ti_sci.c @@ -87,11 +87,18 @@ struct ti_sci_info { struct mbox_chan chan_notify; struct ti_sci_xfer xfer; struct list_head list; + struct list_head dev_list; bool is_secure; u8 host_id; u8 seq; };
+struct ti_sci_exclusive_dev { + u32 id; + u32 count; + struct list_head list; +}; + #define handle_to_ti_sci_info(h) container_of(h, struct ti_sci_info, handle)
/** @@ -427,6 +434,47 @@ static int ti_sci_cmd_set_board_config_pm(const struct ti_sci_handle *handle, addr, size); }
+static struct ti_sci_exclusive_dev +*ti_sci_get_exclusive_dev(struct list_head *dev_list, u32 id) +{ + struct ti_sci_exclusive_dev *dev; + + list_for_each_entry(dev, dev_list, list) + if (dev->id == id) + return dev; + + return NULL; +} + +static void ti_sci_add_exclusive_dev(struct ti_sci_info *info, u32 id) +{ + struct ti_sci_exclusive_dev *dev; + + dev = ti_sci_get_exclusive_dev(&info->dev_list, id); + if (dev) { + dev->count++; + return; + } + + dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev->id = id; + dev->count = 1; + INIT_LIST_HEAD(&dev->list); + list_add_tail(&dev->list, &info->dev_list); +} + +static void ti_sci_delete_exclusive_dev(struct ti_sci_info *info, u32 id) +{ + struct ti_sci_exclusive_dev *dev; + + dev = ti_sci_get_exclusive_dev(&info->dev_list, id); + if (!dev) + return; + + if (dev->count > 0) + dev->count--; +} + /** * ti_sci_set_device_state() - Set device state helper * @handle: pointer to TI SCI handle @@ -474,6 +522,11 @@ static int ti_sci_set_device_state(const struct ti_sci_handle *handle, if (!ti_sci_is_response_ack(resp)) return -ENODEV;
+ if (state == MSG_DEVICE_SW_STATE_AUTO_OFF) + ti_sci_delete_exclusive_dev(info, id); + else if (flags & MSG_FLAG_DEVICE_EXCLUSIVE) + ti_sci_add_exclusive_dev(info, id); + return ret; }
@@ -651,6 +704,25 @@ static int ti_sci_cmd_put_device(const struct ti_sci_handle *handle, u32 id) MSG_DEVICE_SW_STATE_AUTO_OFF); }
+static +int ti_sci_cmd_release_exclusive_devices(const struct ti_sci_handle *handle) +{ + struct ti_sci_exclusive_dev *dev, *tmp; + struct ti_sci_info *info; + int i, cnt; + + info = handle_to_ti_sci_info(handle); + + list_for_each_entry_safe(dev, tmp, &info->dev_list, list) { + cnt = dev->count; + debug("%s: id = %d, cnt = %d\n", __func__, dev->id, cnt); + for (i = 0; i < cnt; i++) + ti_sci_cmd_put_device(handle, dev->id); + } + + return 0; +} + /** * ti_sci_cmd_dev_is_valid() - Is the device valid * @handle: Pointer to TISCI handle as retrieved by *ti_sci_get_handle @@ -2839,6 +2911,7 @@ static void ti_sci_setup_ops(struct ti_sci_info *info) dops->is_transitioning = ti_sci_cmd_dev_is_trans; dops->set_device_resets = ti_sci_cmd_set_device_resets; dops->get_device_resets = ti_sci_cmd_get_device_resets; + dops->release_exclusive_devices = ti_sci_cmd_release_exclusive_devices;
cops->get_clock = ti_sci_cmd_get_clock; cops->idle_clock = ti_sci_cmd_idle_clock; @@ -3033,6 +3106,8 @@ static int ti_sci_probe(struct udevice *dev)
ret = ti_sci_cmd_get_revision(&info->handle);
+ INIT_LIST_HEAD(&info->dev_list); + return ret; }
diff --git a/include/linux/soc/ti/ti_sci_protocol.h b/include/linux/soc/ti/ti_sci_protocol.h index cd6e5853b4..1cba8d9b79 100644 --- a/include/linux/soc/ti/ti_sci_protocol.h +++ b/include/linux/soc/ti/ti_sci_protocol.h @@ -105,6 +105,9 @@ struct ti_sci_board_ops { * -reset_state: pointer to u32 which will retrieve resets * Returns 0 for successful request, else returns * corresponding error message. + * @release_exclusive_devices: Command to release all the exclusive devices + * attached to this host. This should be used very carefully + * and only at the end of execution of your software. * * NOTE: for all these functions, the following parameters are generic in * nature: @@ -137,6 +140,7 @@ struct ti_sci_dev_ops { u32 reset_state); int (*get_device_resets)(const struct ti_sci_handle *handle, u32 id, u32 *reset_state); + int (*release_exclusive_devices)(const struct ti_sci_handle *handle); };
/**

On Fri, Jun 07, 2019 at 07:24:41PM +0530, Lokesh Vutla wrote:
Any host while requesting for a device can request for its exclusive access. If an exclusive permission is obtained then it is the host's responsibility to release the device before the software entity on the host completes its execution. Else any other host's request for the device will be nacked. So add a command that releases all the exclusive devices that is acquired by the current host. This should be used with utmost care and can be called only at the end of the execution.
Signed-off-by: Lokesh Vutla lokeshvutla@ti.com
Applied to u-boot/master, thanks!

From: Andreas Dannenberg dannenberg@ti.com
Rather than simply parking the R5 core in WFE after starting up ATF on A53 instead use SYSFW API to properly shut down the R5 CPU cores as well as associated timer resources that were pre-allocated. This allows software further downstream to properly and gracefully bring the R5 cores back online if desired.
Signed-off-by: Andreas Dannenberg dannenberg@ti.com Signed-off-by: Lokesh Vutla lokeshvutla@ti.com --- arch/arm/mach-k3/am6_init.c | 62 +++++++++++++++++++++++ arch/arm/mach-k3/common.c | 6 ++- arch/arm/mach-k3/include/mach/sys_proto.h | 2 +- 3 files changed, 68 insertions(+), 2 deletions(-)
diff --git a/arch/arm/mach-k3/am6_init.c b/arch/arm/mach-k3/am6_init.c index cb96581bfb..31fa1c8803 100644 --- a/arch/arm/mach-k3/am6_init.c +++ b/arch/arm/mach-k3/am6_init.c @@ -16,6 +16,7 @@ #include <dm.h> #include <dm/uclass-internal.h> #include <dm/pinctrl.h> +#include <linux/soc/ti/ti_sci_protocol.h>
#ifdef CONFIG_SPL_BUILD static void mmr_unlock(u32 base, u32 partition) @@ -214,3 +215,64 @@ void reset_cpu(ulong ignored) { } #endif + +#ifdef CONFIG_SYS_K3_SPL_ATF + +#define AM6_DEV_MCU_RTI0 134 +#define AM6_DEV_MCU_RTI1 135 +#define AM6_DEV_MCU_ARMSS0_CPU0 159 +#define AM6_DEV_MCU_ARMSS0_CPU1 245 + +void release_resources_for_core_shutdown(void) +{ + struct udevice *dev; + struct ti_sci_handle *ti_sci; + struct ti_sci_dev_ops *dev_ops; + struct ti_sci_proc_ops *proc_ops; + int ret; + u32 i; + + const u32 put_device_ids[] = { + AM6_DEV_MCU_RTI0, + AM6_DEV_MCU_RTI1, + }; + + /* Get handle to Device Management and Security Controller (SYSFW) */ + ret = uclass_get_device_by_name(UCLASS_FIRMWARE, "dmsc", &dev); + if (ret) + panic("Failed to get handle to SYSFW (%d)\n", ret); + + ti_sci = (struct ti_sci_handle *)(ti_sci_get_handle_from_sysfw(dev)); + dev_ops = &ti_sci->ops.dev_ops; + proc_ops = &ti_sci->ops.proc_ops; + + /* Iterate through list of devices to put (shutdown) */ + for (i = 0; i < ARRAY_SIZE(put_device_ids); i++) { + u32 id = put_device_ids[i]; + + ret = dev_ops->put_device(ti_sci, id); + if (ret) + panic("Failed to put device %u (%d)\n", id, ret); + } + + const u32 put_core_ids[] = { + AM6_DEV_MCU_ARMSS0_CPU1, + AM6_DEV_MCU_ARMSS0_CPU0, /* Handle CPU0 after CPU1 */ + }; + + /* Iterate through list of cores to put (shutdown) */ + for (i = 0; i < ARRAY_SIZE(put_core_ids); i++) { + u32 id = put_core_ids[i]; + + /* + * Queue up the core shutdown request. Note that this call + * needs to be followed up by an actual invocation of an WFE + * or WFI CPU instruction. + */ + ret = proc_ops->proc_shutdown_no_wait(ti_sci, id); + if (ret) + panic("Failed sending core %u shutdown message (%d)\n", + id, ret); + } +} +#endif diff --git a/arch/arm/mach-k3/common.c b/arch/arm/mach-k3/common.c index 03f01d07ea..ee84d44de8 100644 --- a/arch/arm/mach-k3/common.c +++ b/arch/arm/mach-k3/common.c @@ -13,6 +13,7 @@ #include <remoteproc.h> #include <linux/soc/ti/ti_sci_protocol.h> #include <fdt_support.h> +#include <asm/arch/sys_proto.h>
struct ti_sci_handle *get_ti_sci_handle(void) { @@ -51,7 +52,10 @@ void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image) if (ret) panic("%s: ATF failed to start on rproc (%d)\n", __func__, ret);
- debug("ATF started. Waiting indefinitely...\n"); + debug("Releasing resources...\n"); + release_resources_for_core_shutdown(); + + debug("Finalizing core shutdown...\n"); while (1) asm volatile("wfe"); } diff --git a/arch/arm/mach-k3/include/mach/sys_proto.h b/arch/arm/mach-k3/include/mach/sys_proto.h index 787a274492..45832b45a1 100644 --- a/arch/arm/mach-k3/include/mach/sys_proto.h +++ b/arch/arm/mach-k3/include/mach/sys_proto.h @@ -13,5 +13,5 @@ u32 wait_on_value(u32 read_bit_mask, u32 match_value, void *read_addr, struct ti_sci_handle *get_ti_sci_handle(void); int fdt_fixup_msmc_ram(void *blob, char *parent_path, char *node_name); int do_board_detect(void); - +void release_resources_for_core_shutdown(void); #endif

On Fri, Jun 07, 2019 at 07:24:42PM +0530, Lokesh Vutla wrote:
From: Andreas Dannenberg dannenberg@ti.com
Rather than simply parking the R5 core in WFE after starting up ATF on A53 instead use SYSFW API to properly shut down the R5 CPU cores as well as associated timer resources that were pre-allocated. This allows software further downstream to properly and gracefully bring the R5 cores back online if desired.
Signed-off-by: Andreas Dannenberg dannenberg@ti.com Signed-off-by: Lokesh Vutla lokeshvutla@ti.com
Applied to u-boot/master, thanks!

Release all the exclusive devices held by SPL.
Signed-off-by: Lokesh Vutla lokeshvutla@ti.com --- arch/arm/mach-k3/common.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/arch/arm/mach-k3/common.c b/arch/arm/mach-k3/common.c index ee84d44de8..4e7fe2076c 100644 --- a/arch/arm/mach-k3/common.c +++ b/arch/arm/mach-k3/common.c @@ -30,8 +30,12 @@ struct ti_sci_handle *get_ti_sci_handle(void) #ifdef CONFIG_SYS_K3_SPL_ATF void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image) { + struct ti_sci_handle *ti_sci = get_ti_sci_handle(); int ret;
+ /* Release all the exclusive devices held by SPL before starting ATF */ + ti_sci->ops.dev_ops.release_exclusive_devices(ti_sci); + /* * It is assumed that remoteproc device 1 is the corresponding * Cortex-A core which runs ATF. Make sure DT reflects the same.

On Fri, Jun 07, 2019 at 07:24:43PM +0530, Lokesh Vutla wrote:
Release all the exclusive devices held by SPL.
Signed-off-by: Lokesh Vutla lokeshvutla@ti.com
Applied to u-boot/master, thanks!

Certain drivers want to attach private data corresponding to each power domain. This data might be specific be to the drvier. So add a priv entry into the power_domain structure.
Signed-off-by: Lokesh Vutla lokeshvutla@ti.com --- include/power-domain.h | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-)
diff --git a/include/power-domain.h b/include/power-domain.h index 00996057b0..ec2b70e0b5 100644 --- a/include/power-domain.h +++ b/include/power-domain.h @@ -55,23 +55,12 @@ struct udevice; * * @dev: The device which implements the power domain. * @id: The power domain ID within the provider. - * - * Currently, the power domain API assumes that a single integer ID is enough - * to identify and configure any power domain for any power domain provider. If - * this assumption becomes invalid in the future, the struct could be expanded - * to either (a) add more fields to allow power domain providers to store - * additional information, or (b) replace the id field with an opaque pointer, - * which the provider would dynamically allocate during its .of_xlate op, and - * process during is .request op. This may require the addition of an extra op - * to clean up the allocation. + * @priv: Private data corresponding to each power domain. */ struct power_domain { struct udevice *dev; - /* - * Written by of_xlate. We assume a single id is enough for now. In the - * future, we might add more fields here. - */ unsigned long id; + void *priv; };
/**

On Fri, Jun 07, 2019 at 07:24:44PM +0530, Lokesh Vutla wrote:
Certain drivers want to attach private data corresponding to each power domain. This data might be specific be to the drvier. So add a priv entry into the power_domain structure.
Signed-off-by: Lokesh Vutla lokeshvutla@ti.com
Applied to u-boot/master, thanks!

TISCI protocol supports for enabling the device either with exclusive permissions for the requesting host or with sharing across the hosts. There are certain devices which are exclusive to Linux context and there are certain devices that are shared across different host contexts. So add support for getting this information from DT by increasing the power-domain cells to 2.
Signed-off-by: Lokesh Vutla lokeshvutla@ti.com --- doc/device-tree-bindings/power/ti,sci-pm-domain.txt | 11 +++++++++-- include/dt-bindings/soc/ti,sci_pm_domain.h | 9 +++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) create mode 100644 include/dt-bindings/soc/ti,sci_pm_domain.h
diff --git a/doc/device-tree-bindings/power/ti,sci-pm-domain.txt b/doc/device-tree-bindings/power/ti,sci-pm-domain.txt index 0e190e20fe..72d9fbc833 100644 --- a/doc/device-tree-bindings/power/ti,sci-pm-domain.txt +++ b/doc/device-tree-bindings/power/ti,sci-pm-domain.txt @@ -17,8 +17,15 @@ child of the sysfw node. Required Properties: -------------------- - compatible: Must be "ti,sci-pm-domain" -- #power-domain-cells: Must be 1 so that an id can be provided in each - device node. +- #power-domain-cells: Can be one of the following: + 1: Containing the device id of each node + 2: First entry should be device id + Second entry should be one of the floowing: + TI_SCI_PD_EXCLUSIVE: To allow device to be + exclusively controlled by + the requesting hosts. + TI_SCI_PD_SHARED: To allow device to be shared + by multiple hosts.
Example (AM65x): ---------------- diff --git a/include/dt-bindings/soc/ti,sci_pm_domain.h b/include/dt-bindings/soc/ti,sci_pm_domain.h new file mode 100644 index 0000000000..8f2a7360b6 --- /dev/null +++ b/include/dt-bindings/soc/ti,sci_pm_domain.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef __DT_BINDINGS_TI_SCI_PM_DOMAIN_H +#define __DT_BINDINGS_TI_SCI_PM_DOMAIN_H + +#define TI_SCI_PD_EXCLUSIVE 1 +#define TI_SCI_PD_SHARED 0 + +#endif /* __DT_BINDINGS_TI_SCI_PM_DOMAIN_H */

On Fri, Jun 07, 2019 at 07:24:45PM +0530, Lokesh Vutla wrote:
TISCI protocol supports for enabling the device either with exclusive permissions for the requesting host or with sharing across the hosts. There are certain devices which are exclusive to Linux context and there are certain devices that are shared across different host contexts. So add support for getting this information from DT by increasing the power-domain cells to 2.
Signed-off-by: Lokesh Vutla lokeshvutla@ti.com
Applied to u-boot/master, thanks!

TISCI protocol supports for enabling the device either with exclusive permissions for the requesting host or with sharing across the hosts. There are certain devices which are exclusive to Linux context and there are certain devices that are shared across different host contexts. So add support for getting this information from DT by increasing the power-domain cells to 2.
For keeping the DT backward compatibility intact, defaulting the device permissions to set the exclusive flag set. In this case the power-domain-cells is 1.
Signed-off-by: Lokesh Vutla lokeshvutla@ti.com --- drivers/power/domain/ti-sci-power-domain.c | 31 +++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-)
diff --git a/drivers/power/domain/ti-sci-power-domain.c b/drivers/power/domain/ti-sci-power-domain.c index aafde62cbf..b9cd37b612 100644 --- a/drivers/power/domain/ti-sci-power-domain.c +++ b/drivers/power/domain/ti-sci-power-domain.c @@ -13,6 +13,7 @@ #include <errno.h> #include <power-domain-uclass.h> #include <linux/soc/ti/ti_sci_protocol.h> +#include <dt-bindings/soc/ti,sci_pm_domain.h>
/** * struct ti_sci_power_domain_data - pm domain controller information structure @@ -56,11 +57,16 @@ static int ti_sci_power_domain_on(struct power_domain *pd) struct ti_sci_power_domain_data *data = dev_get_priv(pd->dev); const struct ti_sci_handle *sci = data->sci; const struct ti_sci_dev_ops *dops = &sci->ops.dev_ops; + u8 flags = (uintptr_t)pd->priv; int ret;
debug("%s(pd=%p)\n", __func__, pd);
- ret = dops->get_device(sci, pd->id); + if (flags & TI_SCI_PD_EXCLUSIVE) + ret = dops->get_device_exclusive(sci, pd->id); + else + ret = dops->get_device(sci, pd->id); + if (ret) dev_err(power_domain->dev, "%s: get_device failed (%d)\n", __func__, ret); @@ -85,6 +91,28 @@ static int ti_sci_power_domain_off(struct power_domain *pd) return ret; }
+static int ti_sci_power_domain_of_xlate(struct power_domain *pd, + struct ofnode_phandle_args *args) +{ + u8 flags; + + debug("%s(power_domain=%p)\n", __func__, pd); + + if (args->args_count < 1) { + debug("Invalid args_count: %d\n", args->args_count); + return -EINVAL; + } + + pd->id = args->args[0]; + /* By default request for device exclusive */ + flags = TI_SCI_PD_EXCLUSIVE; + if (args->args_count == 2) + flags = args->args[1] & TI_SCI_PD_EXCLUSIVE; + pd->priv = (void *)(uintptr_t)flags; + + return 0; +} + static const struct udevice_id ti_sci_power_domain_of_match[] = { { .compatible = "ti,sci-pm-domain" }, { /* sentinel */ } @@ -95,6 +123,7 @@ static struct power_domain_ops ti_sci_power_domain_ops = { .free = ti_sci_power_domain_free, .on = ti_sci_power_domain_on, .off = ti_sci_power_domain_off, + .of_xlate = ti_sci_power_domain_of_xlate, };
U_BOOT_DRIVER(ti_sci_pm_domains) = {

On Fri, Jun 07, 2019 at 07:24:46PM +0530, Lokesh Vutla wrote:
TISCI protocol supports for enabling the device either with exclusive permissions for the requesting host or with sharing across the hosts. There are certain devices which are exclusive to Linux context and there are certain devices that are shared across different host contexts. So add support for getting this information from DT by increasing the power-domain cells to 2.
For keeping the DT backward compatibility intact, defaulting the device permissions to set the exclusive flag set. In this case the power-domain-cells is 1.
Signed-off-by: Lokesh Vutla lokeshvutla@ti.com
Applied to u-boot/master, thanks!

Update the power-domain-cells to 2 and add the permissions to each node. Mark the following nodes accessed by r5 as shared: - DDR node - main uart 0
Signed-off-by: Lokesh Vutla lokeshvutla@ti.com --- arch/arm/dts/k3-am65-main.dtsi | 10 +++++----- arch/arm/dts/k3-am65-mcu.dtsi | 2 +- arch/arm/dts/k3-am65-wakeup.dtsi | 4 ++-- arch/arm/dts/k3-am65.dtsi | 1 + arch/arm/dts/k3-am654-base-board-u-boot.dtsi | 2 +- arch/arm/dts/k3-am654-ddr.dtsi | 4 ++-- arch/arm/dts/k3-am654-r5-base-board.dts | 8 ++++++-- 7 files changed, 18 insertions(+), 13 deletions(-)
diff --git a/arch/arm/dts/k3-am65-main.dtsi b/arch/arm/dts/k3-am65-main.dtsi index 39fec03b4a..7d03706057 100644 --- a/arch/arm/dts/k3-am65-main.dtsi +++ b/arch/arm/dts/k3-am65-main.dtsi @@ -89,7 +89,7 @@ sdhci0: sdhci@4f80000 { compatible = "ti,am654-sdhci-5.1"; reg = <0x0 0x4f80000 0x0 0x260>, <0x0 0x4f90000 0x0 0x134>; - power-domains = <&k3_pds 47>; + power-domains = <&k3_pds 47 TI_SCI_PD_EXCLUSIVE>; clocks = <&k3_clks 47 0>, <&k3_clks 47 1>; clock-names = "clk_ahb", "clk_xin"; interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>; @@ -108,7 +108,7 @@ #size-cells = <0>; clock-names = "fck"; clocks = <&k3_clks 110 1>; - power-domains = <&k3_pds 110>; + power-domains = <&k3_pds 110 TI_SCI_PD_EXCLUSIVE>; };
main_i2c1: i2c@2010000 { @@ -119,7 +119,7 @@ #size-cells = <0>; clock-names = "fck"; clocks = <&k3_clks 111 1>; - power-domains = <&k3_pds 111>; + power-domains = <&k3_pds 111 TI_SCI_PD_EXCLUSIVE>; };
main_i2c2: i2c@2020000 { @@ -130,7 +130,7 @@ #size-cells = <0>; clock-names = "fck"; clocks = <&k3_clks 112 1>; - power-domains = <&k3_pds 112>; + power-domains = <&k3_pds 112 TI_SCI_PD_EXCLUSIVE>; };
main_i2c3: i2c@2030000 { @@ -141,6 +141,6 @@ #size-cells = <0>; clock-names = "fck"; clocks = <&k3_clks 113 1>; - power-domains = <&k3_pds 113>; + power-domains = <&k3_pds 113 TI_SCI_PD_EXCLUSIVE>; }; }; diff --git a/arch/arm/dts/k3-am65-mcu.dtsi b/arch/arm/dts/k3-am65-mcu.dtsi index 1fd027748e..c9bfd9b80f 100644 --- a/arch/arm/dts/k3-am65-mcu.dtsi +++ b/arch/arm/dts/k3-am65-mcu.dtsi @@ -24,6 +24,6 @@ #size-cells = <0>; clock-names = "fck"; clocks = <&k3_clks 114 1>; - power-domains = <&k3_pds 114>; + power-domains = <&k3_pds 114 TI_SCI_PD_EXCLUSIVE>; }; }; diff --git a/arch/arm/dts/k3-am65-wakeup.dtsi b/arch/arm/dts/k3-am65-wakeup.dtsi index 1f85006f55..2676d6035b 100644 --- a/arch/arm/dts/k3-am65-wakeup.dtsi +++ b/arch/arm/dts/k3-am65-wakeup.dtsi @@ -20,7 +20,7 @@
k3_pds: power-controller { compatible = "ti,sci-pm-domain"; - #power-domain-cells = <1>; + #power-domain-cells = <2>; };
k3_clks: clocks { @@ -60,6 +60,6 @@ #size-cells = <0>; clock-names = "fck"; clocks = <&k3_clks 115 1>; - power-domains = <&k3_pds 115>; + power-domains = <&k3_pds 115 TI_SCI_PD_EXCLUSIVE>; }; }; diff --git a/arch/arm/dts/k3-am65.dtsi b/arch/arm/dts/k3-am65.dtsi index 50f4be2047..3aeb69e663 100644 --- a/arch/arm/dts/k3-am65.dtsi +++ b/arch/arm/dts/k3-am65.dtsi @@ -9,6 +9,7 @@ #include <dt-bindings/interrupt-controller/irq.h> #include <dt-bindings/interrupt-controller/arm-gic.h> #include <dt-bindings/pinctrl/k3.h> +#include <dt-bindings/soc/ti,sci_pm_domain.h>
/ { model = "Texas Instruments K3 AM654 SoC"; diff --git a/arch/arm/dts/k3-am654-base-board-u-boot.dtsi b/arch/arm/dts/k3-am654-base-board-u-boot.dtsi index e21562252f..41ea152893 100644 --- a/arch/arm/dts/k3-am654-base-board-u-boot.dtsi +++ b/arch/arm/dts/k3-am654-base-board-u-boot.dtsi @@ -24,7 +24,7 @@ reg = <0x0 0x4FA0000 0x0 0x1000>, <0x0 0x4FB0000 0x0 0x400>; clocks = <&k3_clks 48 1>; - power-domains = <&k3_pds 48>; + power-domains = <&k3_pds 48 TI_SCI_PD_EXCLUSIVE>; max-frequency = <25000000>; ti,otap-del-sel = <0x2>; ti,trm-icp = <0x8>; diff --git a/arch/arm/dts/k3-am654-ddr.dtsi b/arch/arm/dts/k3-am654-ddr.dtsi index 964eb173eb..622a3edb61 100644 --- a/arch/arm/dts/k3-am654-ddr.dtsi +++ b/arch/arm/dts/k3-am654-ddr.dtsi @@ -11,8 +11,8 @@ <0x0 0x02988000 0x0 0x2000>; reg-names = "ss", "ctl", "phy"; clocks = <&k3_clks 20 0>; - power-domains = <&k3_pds 20>, - <&k3_pds 244>; + power-domains = <&k3_pds 20 TI_SCI_PD_SHARED>, + <&k3_pds 244 TI_SCI_PD_SHARED>; assigned-clocks = <&k3_clks 20 1>; assigned-clock-rates = <DDR_PLL_FREQUENCY>; u-boot,dm-spl; diff --git a/arch/arm/dts/k3-am654-r5-base-board.dts b/arch/arm/dts/k3-am654-r5-base-board.dts index 9d9b3d5852..7ed307f0d8 100644 --- a/arch/arm/dts/k3-am654-r5-base-board.dts +++ b/arch/arm/dts/k3-am654-r5-base-board.dts @@ -32,8 +32,8 @@ a53_0: a53@0 { compatible = "ti,am654-rproc"; reg = <0x0 0x00a90000 0x0 0x10>; - power-domains = <&k3_pds 61>, - <&k3_pds 202>; + power-domains = <&k3_pds 61 TI_SCI_PD_EXCLUSIVE>, + <&k3_pds 202 TI_SCI_PD_EXCLUSIVE>; resets = <&k3_reset 202 0>; assigned-clocks = <&k3_clks 202 0>; assigned-clock-rates = <800000000>; @@ -118,6 +118,10 @@ status = "okay"; };
+&main_uart0 { + power-domains = <&k3_pds 146 TI_SCI_PD_SHARED>; +}; + &wkup_pmx0 { u-boot,dm-spl; wkup_uart0_pins_default: wkup_uart0_pins_default {

On Fri, Jun 07, 2019 at 07:24:47PM +0530, Lokesh Vutla wrote:
Update the power-domain-cells to 2 and add the permissions to each node. Mark the following nodes accessed by r5 as shared:
- DDR node
- main uart 0
Signed-off-by: Lokesh Vutla lokeshvutla@ti.com
Applied to u-boot/master, thanks!
participants (2)
-
Lokesh Vutla
-
Tom Rini