Merge changes from topic "ti-cluster-power" into integration
* changes: ti: k3: drivers: ti_sci: Put sequence number in coherent memory ti: k3: drivers: ti_sci: Remove indirect structure of const data ti: k3: common: Enable ARM cluster power down ti: k3: common: Rename device IDs to be more consistent
This commit is contained in:
commit
29763ac260
|
@ -27,5 +27,6 @@
|
|||
|
||||
#define PLAT_PROC_START_ID 32
|
||||
#define PLAT_PROC_DEVICE_START_ID 202
|
||||
#define PLAT_CLUSTER_DEVICE_START_ID 198
|
||||
|
||||
#endif /* BOARD_DEF_H */
|
||||
|
|
|
@ -20,32 +20,10 @@
|
|||
#include "ti_sci_protocol.h"
|
||||
#include "ti_sci.h"
|
||||
|
||||
/**
|
||||
* struct ti_sci_desc - Description of SoC integration
|
||||
* @host_id: Host identifier representing the compute entity
|
||||
* @max_msg_size: Maximum size of data per message that can be handled
|
||||
*/
|
||||
struct ti_sci_desc {
|
||||
uint8_t host_id;
|
||||
int max_msg_size;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct ti_sci_info - Structure representing a TI SCI instance
|
||||
* @desc: SoC description for this instance
|
||||
* @seq: Seq id used for verification for tx and rx message
|
||||
*/
|
||||
struct ti_sci_info {
|
||||
const struct ti_sci_desc desc;
|
||||
uint8_t seq;
|
||||
};
|
||||
|
||||
static struct ti_sci_info info = {
|
||||
.desc = {
|
||||
.host_id = TI_SCI_HOST_ID,
|
||||
.max_msg_size = TI_SCI_MAX_MESSAGE_SIZE,
|
||||
},
|
||||
};
|
||||
#if USE_COHERENT_MEM
|
||||
__section("tzfw_coherent_mem")
|
||||
#endif
|
||||
static uint8_t message_sequence;
|
||||
|
||||
/**
|
||||
* struct ti_sci_xfer - Structure representing a message flow
|
||||
|
@ -82,16 +60,16 @@ static int ti_sci_setup_one_xfer(uint16_t msg_type, uint32_t msg_flags,
|
|||
struct ti_sci_msg_hdr *hdr;
|
||||
|
||||
/* Ensure we have sane transfer sizes */
|
||||
if (rx_message_size > info.desc.max_msg_size ||
|
||||
tx_message_size > info.desc.max_msg_size ||
|
||||
if (rx_message_size > TI_SCI_MAX_MESSAGE_SIZE ||
|
||||
tx_message_size > TI_SCI_MAX_MESSAGE_SIZE ||
|
||||
rx_message_size < sizeof(*hdr) ||
|
||||
tx_message_size < sizeof(*hdr))
|
||||
return -ERANGE;
|
||||
|
||||
hdr = (struct ti_sci_msg_hdr *)tx_buf;
|
||||
hdr->seq = ++info.seq;
|
||||
hdr->seq = ++message_sequence;
|
||||
hdr->type = msg_type;
|
||||
hdr->host = info.desc.host_id;
|
||||
hdr->host = TI_SCI_HOST_ID;
|
||||
hdr->flags = msg_flags | TI_SCI_FLAG_REQ_ACK_ON_PROCESSED;
|
||||
|
||||
xfer->tx_message.buf = tx_buf;
|
||||
|
@ -131,7 +109,7 @@ static inline int ti_sci_get_response(struct ti_sci_xfer *xfer,
|
|||
hdr = (struct ti_sci_msg_hdr *)msg->buf;
|
||||
|
||||
/* Sanity check for message response */
|
||||
if (hdr->seq == info.seq)
|
||||
if (hdr->seq == message_sequence)
|
||||
break;
|
||||
else
|
||||
WARN("Message with sequence ID %u is not expected\n", hdr->seq);
|
||||
|
@ -141,9 +119,9 @@ static inline int ti_sci_get_response(struct ti_sci_xfer *xfer,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (msg->len > info.desc.max_msg_size) {
|
||||
if (msg->len > TI_SCI_MAX_MESSAGE_SIZE) {
|
||||
ERROR("Unable to handle %lu xfer (max %d)\n",
|
||||
msg->len, info.desc.max_msg_size);
|
||||
msg->len, TI_SCI_MAX_MESSAGE_SIZE);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -425,13 +403,13 @@ int ti_sci_device_put_no_wait(uint32_t id)
|
|||
int ret;
|
||||
|
||||
/* Ensure we have sane transfer size */
|
||||
if (sizeof(req) > info.desc.max_msg_size)
|
||||
if (sizeof(req) > TI_SCI_MAX_MESSAGE_SIZE)
|
||||
return -ERANGE;
|
||||
|
||||
hdr = (struct ti_sci_msg_hdr *)&req;
|
||||
hdr->seq = ++info.seq;
|
||||
hdr->seq = ++message_sequence;
|
||||
hdr->type = TI_SCI_MSG_SET_DEVICE_STATE;
|
||||
hdr->host = info.desc.host_id;
|
||||
hdr->host = TI_SCI_HOST_ID;
|
||||
/* Setup with NORESPONSE flag to keep response queue clean */
|
||||
hdr->flags = TI_SCI_FLAG_REQ_GENERIC_NORESPONSE;
|
||||
|
||||
|
@ -1408,13 +1386,13 @@ int ti_sci_proc_set_boot_ctrl_no_wait(uint8_t proc_id,
|
|||
int ret;
|
||||
|
||||
/* Ensure we have sane transfer size */
|
||||
if (sizeof(req) > info.desc.max_msg_size)
|
||||
if (sizeof(req) > TI_SCI_MAX_MESSAGE_SIZE)
|
||||
return -ERANGE;
|
||||
|
||||
hdr = (struct ti_sci_msg_hdr *)&req;
|
||||
hdr->seq = ++info.seq;
|
||||
hdr->seq = ++message_sequence;
|
||||
hdr->type = TISCI_MSG_SET_PROC_BOOT_CTRL;
|
||||
hdr->host = info.desc.host_id;
|
||||
hdr->host = TI_SCI_HOST_ID;
|
||||
/* Setup with NORESPONSE flag to keep response queue clean */
|
||||
hdr->flags = TI_SCI_FLAG_REQ_GENERIC_NORESPONSE;
|
||||
|
||||
|
@ -1650,13 +1628,13 @@ int ti_sci_proc_wait_boot_status_no_wait(uint8_t proc_id,
|
|||
int ret;
|
||||
|
||||
/* Ensure we have sane transfer size */
|
||||
if (sizeof(req) > info.desc.max_msg_size)
|
||||
if (sizeof(req) > TI_SCI_MAX_MESSAGE_SIZE)
|
||||
return -ERANGE;
|
||||
|
||||
hdr = (struct ti_sci_msg_hdr *)&req;
|
||||
hdr->seq = ++info.seq;
|
||||
hdr->seq = ++message_sequence;
|
||||
hdr->type = TISCI_MSG_WAIT_PROC_BOOT_STATUS;
|
||||
hdr->host = info.desc.host_id;
|
||||
hdr->host = TI_SCI_HOST_ID;
|
||||
/* Setup with NORESPONSE flag to keep response queue clean */
|
||||
hdr->flags = TI_SCI_FLAG_REQ_GENERIC_NORESPONSE;
|
||||
|
||||
|
|
|
@ -563,8 +563,13 @@ struct ti_sci_msg_req_set_proc_boot_config {
|
|||
uint32_t config_flags_clear;
|
||||
} __packed;
|
||||
|
||||
/* ARMV8 Control Flags */
|
||||
#define PROC_BOOT_CTRL_FLAG_ARMV8_ACINACTM 0x00000001
|
||||
#define PROC_BOOT_CTRL_FLAG_ARMV8_AINACTS 0x00000002
|
||||
#define PROC_BOOT_CTRL_FLAG_ARMV8_L2FLUSHREQ 0x00000100
|
||||
|
||||
/* R5 Control Flags */
|
||||
#define PROC_BOOT_CTRL_FLAG_R5_CORE_HALT 0x00000001
|
||||
#define PROC_BOOT_CTRL_FLAG_R5_CORE_HALT 0x00000001
|
||||
|
||||
/**
|
||||
* struct ti_sci_msg_req_set_proc_boot_ctrl - Set Processor boot control flags
|
||||
|
@ -618,6 +623,8 @@ struct ti_sci_msg_req_get_proc_boot_status {
|
|||
/* ARMv8 Status Flags */
|
||||
#define PROC_BOOT_STATUS_FLAG_ARMV8_WFE 0x00000001
|
||||
#define PROC_BOOT_STATUS_FLAG_ARMV8_WFI 0x00000002
|
||||
#define PROC_BOOT_STATUS_FLAG_ARMV8_L2F_DONE 0x00000010
|
||||
#define PROC_BOOT_STATUS_FLAG_ARMV8_STANDBYWFIL2 0x00000020
|
||||
|
||||
/* R5 Status Flags */
|
||||
#define PROC_BOOT_STATUS_FLAG_R5_WFE 0x00000001
|
||||
|
|
|
@ -17,6 +17,10 @@
|
|||
#include <k3_gicv3.h>
|
||||
#include <ti_sci.h>
|
||||
|
||||
#define CORE_PWR_STATE(state) ((state)->pwr_domain_state[MPIDR_AFFLVL0])
|
||||
#define CLUSTER_PWR_STATE(state) ((state)->pwr_domain_state[MPIDR_AFFLVL1])
|
||||
#define SYSTEM_PWR_STATE(state) ((state)->pwr_domain_state[PLAT_MAX_PWR_LVL])
|
||||
|
||||
uintptr_t k3_sec_entrypoint;
|
||||
|
||||
static void k3_cpu_standby(plat_local_state_t cpu_state)
|
||||
|
@ -37,30 +41,40 @@ static void k3_cpu_standby(plat_local_state_t cpu_state)
|
|||
|
||||
static int k3_pwr_domain_on(u_register_t mpidr)
|
||||
{
|
||||
int core_id, proc, device, ret;
|
||||
int core, proc_id, device_id, ret;
|
||||
|
||||
core_id = plat_core_pos_by_mpidr(mpidr);
|
||||
if (core_id < 0) {
|
||||
ERROR("Could not get target core id: %d\n", core_id);
|
||||
core = plat_core_pos_by_mpidr(mpidr);
|
||||
if (core < 0) {
|
||||
ERROR("Could not get target core id: %d\n", core);
|
||||
return PSCI_E_INTERN_FAIL;
|
||||
}
|
||||
|
||||
proc = PLAT_PROC_START_ID + core_id;
|
||||
device = PLAT_PROC_DEVICE_START_ID + core_id;
|
||||
proc_id = PLAT_PROC_START_ID + core;
|
||||
device_id = PLAT_PROC_DEVICE_START_ID + core;
|
||||
|
||||
ret = ti_sci_proc_request(proc);
|
||||
ret = ti_sci_proc_request(proc_id);
|
||||
if (ret) {
|
||||
ERROR("Request for processor failed: %d\n", ret);
|
||||
return PSCI_E_INTERN_FAIL;
|
||||
}
|
||||
|
||||
ret = ti_sci_proc_set_boot_cfg(proc, k3_sec_entrypoint, 0, 0);
|
||||
ret = ti_sci_proc_set_boot_cfg(proc_id, k3_sec_entrypoint, 0, 0);
|
||||
if (ret) {
|
||||
ERROR("Request to set core boot address failed: %d\n", ret);
|
||||
return PSCI_E_INTERN_FAIL;
|
||||
}
|
||||
|
||||
ret = ti_sci_device_get(device);
|
||||
/* sanity check these are off before starting a core */
|
||||
ret = ti_sci_proc_set_boot_ctrl(proc_id,
|
||||
0, PROC_BOOT_CTRL_FLAG_ARMV8_L2FLUSHREQ |
|
||||
PROC_BOOT_CTRL_FLAG_ARMV8_AINACTS |
|
||||
PROC_BOOT_CTRL_FLAG_ARMV8_ACINACTM);
|
||||
if (ret) {
|
||||
ERROR("Request to clear boot configuration failed: %d\n", ret);
|
||||
return PSCI_E_INTERN_FAIL;
|
||||
}
|
||||
|
||||
ret = ti_sci_device_get(device_id);
|
||||
if (ret) {
|
||||
ERROR("Request to start core failed: %d\n", ret);
|
||||
return PSCI_E_INTERN_FAIL;
|
||||
|
@ -71,17 +85,35 @@ static int k3_pwr_domain_on(u_register_t mpidr)
|
|||
|
||||
void k3_pwr_domain_off(const psci_power_state_t *target_state)
|
||||
{
|
||||
int core_id, proc, device, ret;
|
||||
int core, cluster, proc_id, device_id, cluster_id, ret;
|
||||
|
||||
/* At very least the local core should be powering down */
|
||||
assert(CORE_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE);
|
||||
|
||||
/* Prevent interrupts from spuriously waking up this cpu */
|
||||
k3_gic_cpuif_disable();
|
||||
|
||||
core_id = plat_my_core_pos();
|
||||
proc = PLAT_PROC_START_ID + core_id;
|
||||
device = PLAT_PROC_DEVICE_START_ID + core_id;
|
||||
core = plat_my_core_pos();
|
||||
cluster = MPIDR_AFFLVL1_VAL(read_mpidr_el1());
|
||||
proc_id = PLAT_PROC_START_ID + core;
|
||||
device_id = PLAT_PROC_DEVICE_START_ID + core;
|
||||
cluster_id = PLAT_CLUSTER_DEVICE_START_ID + (cluster * 2);
|
||||
|
||||
/*
|
||||
* If we are the last core in the cluster then we take a reference to
|
||||
* the cluster device so that it does not get shutdown before we
|
||||
* execute the entire cluster L2 cleaning sequence below.
|
||||
*/
|
||||
if (CLUSTER_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE) {
|
||||
ret = ti_sci_device_get(cluster_id);
|
||||
if (ret) {
|
||||
ERROR("Request to get cluster failed: %d\n", ret);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Start by sending wait for WFI command */
|
||||
ret = ti_sci_proc_wait_boot_status_no_wait(proc,
|
||||
ret = ti_sci_proc_wait_boot_status_no_wait(proc_id,
|
||||
/*
|
||||
* Wait maximum time to give us the best chance to get
|
||||
* to WFI before this command timeouts
|
||||
|
@ -95,11 +127,72 @@ void k3_pwr_domain_off(const psci_power_state_t *target_state)
|
|||
}
|
||||
|
||||
/* Now queue up the core shutdown request */
|
||||
ret = ti_sci_device_put_no_wait(device);
|
||||
ret = ti_sci_device_put_no_wait(device_id);
|
||||
if (ret) {
|
||||
ERROR("Sending core shutdown message failed (%d)\n", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
/* If our cluster is not going down we stop here */
|
||||
if (CLUSTER_PWR_STATE(target_state) != PLAT_MAX_OFF_STATE)
|
||||
return;
|
||||
|
||||
/* set AINACTS */
|
||||
ret = ti_sci_proc_set_boot_ctrl_no_wait(proc_id,
|
||||
PROC_BOOT_CTRL_FLAG_ARMV8_AINACTS, 0);
|
||||
if (ret) {
|
||||
ERROR("Sending set control message failed (%d)\n", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
/* set L2FLUSHREQ */
|
||||
ret = ti_sci_proc_set_boot_ctrl_no_wait(proc_id,
|
||||
PROC_BOOT_CTRL_FLAG_ARMV8_L2FLUSHREQ, 0);
|
||||
if (ret) {
|
||||
ERROR("Sending set control message failed (%d)\n", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
/* wait for L2FLUSHDONE*/
|
||||
ret = ti_sci_proc_wait_boot_status_no_wait(proc_id,
|
||||
UINT8_MAX, 2, UINT8_MAX, UINT8_MAX,
|
||||
PROC_BOOT_STATUS_FLAG_ARMV8_L2F_DONE, 0, 0, 0);
|
||||
if (ret) {
|
||||
ERROR("Sending wait message failed (%d)\n", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
/* clear L2FLUSHREQ */
|
||||
ret = ti_sci_proc_set_boot_ctrl_no_wait(proc_id,
|
||||
0, PROC_BOOT_CTRL_FLAG_ARMV8_L2FLUSHREQ);
|
||||
if (ret) {
|
||||
ERROR("Sending set control message failed (%d)\n", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
/* set ACINACTM */
|
||||
ret = ti_sci_proc_set_boot_ctrl_no_wait(proc_id,
|
||||
PROC_BOOT_CTRL_FLAG_ARMV8_ACINACTM, 0);
|
||||
if (ret) {
|
||||
ERROR("Sending set control message failed (%d)\n", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
/* wait for STANDBYWFIL2 */
|
||||
ret = ti_sci_proc_wait_boot_status_no_wait(proc_id,
|
||||
UINT8_MAX, 2, UINT8_MAX, UINT8_MAX,
|
||||
PROC_BOOT_STATUS_FLAG_ARMV8_STANDBYWFIL2, 0, 0, 0);
|
||||
if (ret) {
|
||||
ERROR("Sending wait message failed (%d)\n", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Now queue up the cluster shutdown request */
|
||||
ret = ti_sci_device_put_no_wait(cluster_id);
|
||||
if (ret) {
|
||||
ERROR("Sending cluster shutdown message failed (%d)\n", ret);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void k3_pwr_domain_on_finish(const psci_power_state_t *target_state)
|
||||
|
|
Loading…
Reference in New Issue