Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
adam.huang
Arm Trusted Firmware
Commits
e92fc067
Unverified
Commit
e92fc067
authored
Jan 22, 2019
by
Antonio Niño Díaz
Committed by
GitHub
Jan 22, 2019
Browse files
Merge pull request #1771 from glneo/core-shutdown
TI K3 Core shutdown changes
parents
87d6bc17
ca3d3414
Changes
4
Hide whitespace changes
Inline
Side-by-side
plat/ti/k3/common/drivers/ti_sci/ti_sci.c
View file @
e92fc067
...
...
@@ -1458,6 +1458,169 @@ int ti_sci_proc_get_boot_status(uint8_t proc_id, uint64_t *bv,
return
0
;
}
/**
* ti_sci_proc_wait_boot_status() - Wait for a processor boot status
*
* @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
*/
int
ti_sci_proc_wait_boot_status
(
uint8_t
proc_id
,
uint8_t
num_wait_iterations
,
uint8_t
num_match_iterations
,
uint8_t
delay_per_iteration_us
,
uint8_t
delay_before_iterations_us
,
uint32_t
status_flags_1_set_all_wait
,
uint32_t
status_flags_1_set_any_wait
,
uint32_t
status_flags_1_clr_all_wait
,
uint32_t
status_flags_1_clr_any_wait
)
{
struct
ti_sci_msg_req_wait_proc_boot_status
req
;
struct
ti_sci_msg_hdr
resp
;
struct
ti_sci_xfer
xfer
;
int
ret
;
ret
=
ti_sci_setup_one_xfer
(
TISCI_MSG_WAIT_PROC_BOOT_STATUS
,
TI_SCI_FLAG_REQ_ACK_ON_PROCESSED
,
&
req
,
sizeof
(
req
),
&
resp
,
sizeof
(
resp
),
&
xfer
);
if
(
ret
)
{
ERROR
(
"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
(
&
xfer
);
if
(
ret
)
{
ERROR
(
"Transfer send failed (%d)
\n
"
,
ret
);
return
ret
;
}
if
(
!
ti_sci_is_response_ack
(
&
resp
))
return
-
ENODEV
;
return
0
;
}
/**
* ti_sci_proc_shutdown() - Shutdown Processor without waiting for ACKs
*
* @proc_id: Processor ID this request is for
* @dev_id: Device identifier this request is for
*
* Return: 0 if all goes well, else appropriate error message
*/
int
ti_sci_proc_shutdown
(
uint8_t
proc_id
,
uint32_t
dev_id
)
{
struct
ti_sci_msg_req_wait_proc_boot_status
wait_req
;
struct
ti_sci_msg_req_set_device_state
set_req
;
/*
* We will not be waiting for this response, but declare one anyway
* to pass to the setup function so the checks will still pass
*/
struct
ti_sci_msg_hdr
resp
;
struct
ti_sci_xfer
xfer
;
int
ret
;
/* Start by sending wait command */
/* Setup with NORESPONSE flag to keep response queue clean */
ret
=
ti_sci_setup_one_xfer
(
TISCI_MSG_WAIT_PROC_BOOT_STATUS
,
TI_SCI_FLAG_REQ_GENERIC_NORESPONSE
,
&
wait_req
,
sizeof
(
wait_req
),
&
resp
,
sizeof
(
resp
),
&
xfer
);
if
(
ret
)
{
ERROR
(
"Message alloc failed (%d)
\n
"
,
ret
);
return
ret
;
}
wait_req
.
processor_id
=
proc_id
;
/*
* Wait maximum time to give us the best chance to get
* to WFI before this command timeouts
*/
wait_req
.
delay_before_iterations_us
=
UINT8_MAX
;
wait_req
.
num_wait_iterations
=
UINT8_MAX
;
wait_req
.
delay_per_iteration_us
=
UINT8_MAX
;
/* TODO: optimize time */
wait_req
.
num_match_iterations
=
2
;
wait_req
.
status_flags_1_set_all_wait
=
0
;
/* Wait for either WFE or WFI */
wait_req
.
status_flags_1_set_any_wait
=
PROC_BOOT_STATUS_FLAG_ARMV8_WFE
|
PROC_BOOT_STATUS_FLAG_ARMV8_WFI
;
wait_req
.
status_flags_1_clr_all_wait
=
0
;
wait_req
.
status_flags_1_clr_any_wait
=
0
;
/* Send wait message */
ret
=
k3_sec_proxy_send
(
SP_HIGH_PRIORITY
,
&
xfer
.
tx_message
);
if
(
ret
)
{
ERROR
(
"Message sending failed (%d)
\n
"
,
ret
);
return
ret
;
}
/* Now queue up the shutdown request */
ret
=
ti_sci_setup_one_xfer
(
TI_SCI_MSG_SET_DEVICE_STATE
,
TI_SCI_FLAG_REQ_GENERIC_NORESPONSE
,
&
set_req
,
sizeof
(
set_req
),
&
resp
,
sizeof
(
resp
),
&
xfer
);
if
(
ret
)
{
ERROR
(
"Message alloc failed (%d)
\n
"
,
ret
);
return
ret
;
}
set_req
.
id
=
dev_id
;
set_req
.
state
=
MSG_DEVICE_SW_STATE_AUTO_OFF
;
/* Send shutdown message */
ret
=
k3_sec_proxy_send
(
SP_HIGH_PRIORITY
,
&
xfer
.
tx_message
);
if
(
ret
)
{
ERROR
(
"Message sending failed (%d)
\n
"
,
ret
);
return
ret
;
}
/* Return without waiting for responses */
return
0
;
}
/**
* ti_sci_init() - Basic initialization
*
...
...
plat/ti/k3/common/drivers/ti_sci/ti_sci.h
View file @
e92fc067
...
...
@@ -179,6 +179,7 @@ int ti_sci_core_reboot(void);
* and then set the processor configuration flags.
* @cert_addr: Memory address at which payload image certificate is located.
* - ti_sci_proc_get_boot_status - Command to get the processor boot status
* - ti_sci_proc_wait_boot_status - Command to wait for a processor boot status
*
* NOTE: for all these functions, the following are generic in nature:
* @proc_id: Processor ID
...
...
@@ -197,6 +198,15 @@ int ti_sci_proc_get_boot_status(uint8_t proc_id, uint64_t *bv,
uint32_t
*
cfg_flags
,
uint32_t
*
ctrl_flags
,
uint32_t
*
sts_flags
);
int
ti_sci_proc_wait_boot_status
(
uint8_t
proc_id
,
uint8_t
num_wait_iterations
,
uint8_t
num_match_iterations
,
uint8_t
delay_per_iteration_us
,
uint8_t
delay_before_iterations_us
,
uint32_t
status_flags_1_set_all_wait
,
uint32_t
status_flags_1_set_any_wait
,
uint32_t
status_flags_1_clr_all_wait
,
uint32_t
status_flags_1_clr_any_wait
);
int
ti_sci_proc_shutdown
(
uint8_t
proc_id
,
uint32_t
dev_id
);
/**
* ti_sci_init() - Basic initialization
...
...
plat/ti/k3/common/drivers/ti_sci/ti_sci_protocol.h
View file @
e92fc067
...
...
@@ -46,6 +46,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
/**
* struct ti_sci_msg_hdr - Generic Message Header for All messages and responses
...
...
@@ -647,4 +648,52 @@ struct ti_sci_msg_resp_get_proc_boot_status {
uint32_t
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
;
uint8_t
processor_id
;
uint8_t
num_wait_iterations
;
uint8_t
num_match_iterations
;
uint8_t
delay_per_iteration_us
;
uint8_t
delay_before_iterations_us
;
uint32_t
status_flags_1_set_all_wait
;
uint32_t
status_flags_1_set_any_wait
;
uint32_t
status_flags_1_clr_all_wait
;
uint32_t
status_flags_1_clr_any_wait
;
}
__packed
;
#endif
/* TI_SCI_PROTOCOL_H */
plat/ti/k3/common/k3_psci.c
View file @
e92fc067
...
...
@@ -81,15 +81,16 @@ 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
,
device
,
ret
;
int
core_id
,
proc
,
device
,
ret
;
/* 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
;
ret
=
ti_sci_
device_put
(
device
);
ret
=
ti_sci_
proc_shutdown
(
proc
,
device
);
if
(
ret
)
{
ERROR
(
"Request to stop core failed: %d
\n
"
,
ret
);
return
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment