Merge pull request #709 from Xilinx/zynqmp-2016-09
xilinx: ZynqMP updates - new SIP calls for bitstream programming - new SIP call to discover the SOC silicon version - support the delay timer
This commit is contained in:
commit
a8de89c974
|
@ -29,6 +29,7 @@
|
|||
*/
|
||||
|
||||
#include <debug.h>
|
||||
#include <generic_delay_timer.h>
|
||||
#include <mmio.h>
|
||||
#include <platform.h>
|
||||
#include <xlat_tables.h>
|
||||
|
@ -89,6 +90,18 @@ static unsigned int zynqmp_get_system_timer_freq(void)
|
|||
return 100000000;
|
||||
}
|
||||
|
||||
unsigned int zynqmp_get_silicon_id(void)
|
||||
{
|
||||
uint32_t id;
|
||||
|
||||
id = mmio_read_32(ZYNQMP_CSU_BASEADDR + ZYNQMP_CSU_IDCODE_OFFSET);
|
||||
|
||||
id &= ZYNQMP_CSU_IDCODE_DEVICE_CODE_MASK | ZYNQMP_CSU_IDCODE_SVD_MASK;
|
||||
id >>= ZYNQMP_CSU_IDCODE_SVD_SHIFT;
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
#if LOG_LEVEL >= LOG_LEVEL_NOTICE
|
||||
static const struct {
|
||||
unsigned int id;
|
||||
|
@ -140,18 +153,6 @@ static const struct {
|
|||
},
|
||||
};
|
||||
|
||||
static unsigned int zynqmp_get_silicon_id(void)
|
||||
{
|
||||
uint32_t id;
|
||||
|
||||
id = mmio_read_32(ZYNQMP_CSU_BASEADDR + ZYNQMP_CSU_IDCODE_OFFSET);
|
||||
|
||||
id &= ZYNQMP_CSU_IDCODE_DEVICE_CODE_MASK | ZYNQMP_CSU_IDCODE_SVD_MASK;
|
||||
id >>= ZYNQMP_CSU_IDCODE_SVD_SHIFT;
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
static char *zynqmp_get_silicon_idcode_name(void)
|
||||
{
|
||||
unsigned int id;
|
||||
|
@ -289,6 +290,8 @@ void zynqmp_config_setup(void)
|
|||
/* Program freq register in System counter and enable system counter. */
|
||||
mmio_write_32(IOU_SCNTRS_BASEFREQ, zynqmp_get_system_timer_freq());
|
||||
mmio_write_32(IOU_SCNTRS_CONTROL, IOU_SCNTRS_CONTROL_EN);
|
||||
|
||||
generic_delay_timer_init();
|
||||
}
|
||||
|
||||
unsigned int plat_get_syscnt_freq2(void)
|
||||
|
|
|
@ -118,11 +118,31 @@ void bl31_early_platform_setup(bl31_params_t *from_bl2,
|
|||
NOTICE("BL31: Non secure code at 0x%lx\n", bl33_image_ep_info.pc);
|
||||
}
|
||||
|
||||
/* Enable the test setup */
|
||||
#ifndef ZYNQMP_TESTING
|
||||
static void zynqmp_testing_setup(void) { }
|
||||
#else
|
||||
static void zynqmp_testing_setup(void)
|
||||
{
|
||||
uint32_t actlr_el3, actlr_el2;
|
||||
|
||||
/* Enable CPU ACTLR AND L2ACTLR RW access from non-secure world */
|
||||
actlr_el3 = read_actlr_el3();
|
||||
actlr_el2 = read_actlr_el2();
|
||||
|
||||
actlr_el3 |= ACTLR_EL3_L2ACTLR_BIT | ACTLR_EL3_CPUACTLR_BIT;
|
||||
actlr_el2 |= ACTLR_EL3_L2ACTLR_BIT | ACTLR_EL3_CPUACTLR_BIT;
|
||||
write_actlr_el3(actlr_el3);
|
||||
write_actlr_el2(actlr_el2);
|
||||
}
|
||||
#endif
|
||||
|
||||
void bl31_platform_setup(void)
|
||||
{
|
||||
/* Initialize the gic cpu and distributor interfaces */
|
||||
plat_arm_gic_driver_init();
|
||||
plat_arm_gic_init();
|
||||
zynqmp_testing_setup();
|
||||
}
|
||||
|
||||
void bl31_plat_runtime_setup(void)
|
||||
|
|
|
@ -56,8 +56,7 @@
|
|||
* little space for growth.
|
||||
*/
|
||||
#ifndef ZYNQMP_ATF_MEM_BASE
|
||||
# define BL31_BASE 0xfffe5000
|
||||
# define BL31_PROGBITS_LIMIT 0xffffa000
|
||||
# define BL31_BASE 0xfffea000
|
||||
# define BL31_LIMIT 0xffffffff
|
||||
#else
|
||||
# define BL31_BASE (ZYNQMP_ATF_MEM_BASE)
|
||||
|
@ -101,11 +100,7 @@
|
|||
******************************************************************************/
|
||||
#define ADDR_SPACE_SIZE (1ull << 32)
|
||||
#define MAX_MMAP_REGIONS 7
|
||||
#if IMAGE_BL32
|
||||
# define MAX_XLAT_TABLES 5
|
||||
#else
|
||||
# define MAX_XLAT_TABLES 4
|
||||
#endif
|
||||
#define MAX_XLAT_TABLES 5
|
||||
|
||||
#define CACHE_WRITEBACK_SHIFT 6
|
||||
#define CACHE_WRITEBACK_GRANULE (1 << CACHE_WRITEBACK_SHIFT)
|
||||
|
|
|
@ -147,7 +147,7 @@ static void zynqmp_pwr_domain_off(const psci_power_state_t *target_state)
|
|||
* invoking CPU_on function, during which resume address will
|
||||
* be set.
|
||||
*/
|
||||
pm_self_suspend(proc->node_id, MAX_LATENCY, 0, 0);
|
||||
pm_self_suspend(proc->node_id, MAX_LATENCY, PM_STATE_CPU_IDLE, 0);
|
||||
}
|
||||
|
||||
static void zynqmp_nopmu_pwr_domain_suspend(const psci_power_state_t *target_state)
|
||||
|
@ -179,6 +179,7 @@ static void zynqmp_nopmu_pwr_domain_suspend(const psci_power_state_t *target_sta
|
|||
|
||||
static void zynqmp_pwr_domain_suspend(const psci_power_state_t *target_state)
|
||||
{
|
||||
unsigned int state;
|
||||
unsigned int cpu_id = plat_my_core_pos();
|
||||
const struct pm_proc *proc = pm_get_proc(cpu_id);
|
||||
|
||||
|
@ -186,15 +187,14 @@ static void zynqmp_pwr_domain_suspend(const psci_power_state_t *target_state)
|
|||
VERBOSE("%s: target_state->pwr_domain_state[%lu]=%x\n",
|
||||
__func__, i, target_state->pwr_domain_state[i]);
|
||||
|
||||
state = target_state->pwr_domain_state[1] > PLAT_MAX_RET_STATE ?
|
||||
PM_STATE_SUSPEND_TO_RAM : PM_STATE_CPU_IDLE;
|
||||
|
||||
/* Send request to PMU to suspend this core */
|
||||
pm_self_suspend(proc->node_id, MAX_LATENCY, 0, zynqmp_sec_entry);
|
||||
pm_self_suspend(proc->node_id, MAX_LATENCY, state, zynqmp_sec_entry);
|
||||
|
||||
/* APU is to be turned off */
|
||||
if (target_state->pwr_domain_state[1] > PLAT_MAX_RET_STATE) {
|
||||
/* Power down L2 cache */
|
||||
pm_set_requirement(NODE_L2, 0, 0, REQ_ACK_NO);
|
||||
/* Send request for OCM retention state */
|
||||
set_ocm_retention();
|
||||
/* disable coherency */
|
||||
plat_arm_interconnect_exit_coherency();
|
||||
}
|
||||
|
@ -242,6 +242,13 @@ static void zynqmp_pwr_domain_suspend_finish(const psci_power_state_t *target_st
|
|||
|
||||
/* enable coherency */
|
||||
plat_arm_interconnect_enter_coherency();
|
||||
/* APU was turned off */
|
||||
if (target_state->pwr_domain_state[1] > PLAT_MAX_RET_STATE) {
|
||||
plat_arm_gic_init();
|
||||
} else {
|
||||
gicv2_cpuif_enable();
|
||||
gicv2_pcpu_distif_init();
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
|
@ -308,7 +315,20 @@ int zynqmp_validate_power_state(unsigned int power_state,
|
|||
{
|
||||
VERBOSE("%s: power_state: 0x%x\n", __func__, power_state);
|
||||
|
||||
/* FIXME: populate req_state */
|
||||
int pstate = psci_get_pstate_type(power_state);
|
||||
|
||||
assert(req_state);
|
||||
|
||||
/* Sanity check the requested state */
|
||||
if (pstate == PSTATE_TYPE_STANDBY)
|
||||
req_state->pwr_domain_state[MPIDR_AFFLVL0] = PLAT_MAX_RET_STATE;
|
||||
else
|
||||
req_state->pwr_domain_state[MPIDR_AFFLVL0] = PLAT_MAX_OFF_STATE;
|
||||
|
||||
/* We expect the 'state id' to be zero */
|
||||
if (psci_get_pstate_id(power_state))
|
||||
return PSCI_E_INVALID_PARAMS;
|
||||
|
||||
return PSCI_E_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@ PROGRAMMABLE_RESET_ADDRESS := 1
|
|||
PSCI_EXTENDED_STATE_ID := 1
|
||||
A53_DISABLE_NON_TEMPORAL_HINT := 0
|
||||
SEPARATE_CODE_AND_RODATA := 1
|
||||
RESET_TO_BL31 := 1
|
||||
|
||||
ifdef ZYNQMP_ATF_MEM_BASE
|
||||
$(eval $(call add_define,ZYNQMP_ATF_MEM_BASE))
|
||||
|
@ -64,6 +65,8 @@ PLAT_INCLUDES := -Iinclude/plat/arm/common/ \
|
|||
|
||||
PLAT_BL_COMMON_SOURCES := lib/xlat_tables/xlat_tables_common.c \
|
||||
lib/xlat_tables/aarch64/xlat_tables.c \
|
||||
drivers/delay_timer/delay_timer.c \
|
||||
drivers/delay_timer/generic_delay_timer.c \
|
||||
drivers/arm/gic/common/gic_common.c \
|
||||
drivers/arm/gic/v2/gicv2_main.c \
|
||||
drivers/arm/gic/v2/gicv2_helpers.c \
|
||||
|
|
|
@ -76,7 +76,7 @@
|
|||
* pm_self_suspend() - PM call for processor to suspend itself
|
||||
* @nid Node id of the processor or subsystem
|
||||
* @latency Requested maximum wakeup latency (not supported)
|
||||
* @state Requested state (not supported)
|
||||
* @state Requested state
|
||||
* @address Resume address
|
||||
*
|
||||
* This is a blocking call, it will return only once PMU has responded.
|
||||
|
@ -97,7 +97,7 @@ enum pm_ret_status pm_self_suspend(enum pm_node_id nid,
|
|||
* Do client specific suspend operations
|
||||
* (e.g. set powerdown request bit)
|
||||
*/
|
||||
pm_client_suspend(proc);
|
||||
pm_client_suspend(proc, state);
|
||||
/* Send request to the PMU */
|
||||
PM_PACK_PAYLOAD6(payload, PM_SELF_SUSPEND, proc->node_id, latency,
|
||||
state, address, (address >> 32));
|
||||
|
@ -476,7 +476,7 @@ enum pm_ret_status pm_mmio_write(uintptr_t address,
|
|||
|
||||
/* Send request to the PMU */
|
||||
PM_PACK_PAYLOAD4(payload, PM_MMIO_WRITE, address, mask, value);
|
||||
return pm_ipi_send(primary_proc, payload);
|
||||
return pm_ipi_send_sync(primary_proc, payload, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -497,3 +497,47 @@ enum pm_ret_status pm_mmio_read(uintptr_t address, unsigned int *value)
|
|||
PM_PACK_PAYLOAD2(payload, PM_MMIO_READ, address);
|
||||
return pm_ipi_send_sync(primary_proc, payload, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_fpga_load() - Load the bitstream into the PL.
|
||||
*
|
||||
* This function provides access to the xilfpga library to load
|
||||
* the Bit-stream into PL.
|
||||
*
|
||||
* address_low: lower 32-bit Linear memory space address
|
||||
*
|
||||
* address_high: higher 32-bit Linear memory space address
|
||||
*
|
||||
* size: Number of 32bit words
|
||||
*
|
||||
* @return Returns status, either success or error+reason
|
||||
*/
|
||||
enum pm_ret_status pm_fpga_load(uint32_t address_low,
|
||||
uint32_t address_high,
|
||||
uint32_t size,
|
||||
uint32_t flags)
|
||||
{
|
||||
uint32_t payload[PAYLOAD_ARG_CNT];
|
||||
|
||||
/* Send request to the PMU */
|
||||
PM_PACK_PAYLOAD5(payload, PM_FPGA_LOAD, address_high, address_low,
|
||||
size, flags);
|
||||
return pm_ipi_send(primary_proc, payload);
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_fpga_get_status() - Read value from fpga status register
|
||||
* @value Value to read
|
||||
*
|
||||
* This function provides access to the xilfpga library to get
|
||||
* the fpga status
|
||||
* @return Returns status, either success or error+reason
|
||||
*/
|
||||
enum pm_ret_status pm_fpga_get_status(unsigned int *value)
|
||||
{
|
||||
uint32_t payload[PAYLOAD_ARG_CNT];
|
||||
|
||||
/* Send request to the PMU */
|
||||
PM_PACK_PAYLOAD1(payload, PM_FPGA_GET_STATUS);
|
||||
return pm_ipi_send_sync(primary_proc, payload, value);
|
||||
}
|
||||
|
|
|
@ -109,4 +109,10 @@ enum pm_ret_status pm_mmio_write(uintptr_t address,
|
|||
unsigned int mask,
|
||||
unsigned int value);
|
||||
enum pm_ret_status pm_mmio_read(uintptr_t address, unsigned int *value);
|
||||
enum pm_ret_status pm_fpga_load(uint32_t address_high,
|
||||
uint32_t address_low,
|
||||
uint32_t size,
|
||||
uint32_t flags);
|
||||
enum pm_ret_status pm_fpga_get_status(unsigned int *value);
|
||||
|
||||
#endif /* _PM_API_SYS_H_ */
|
||||
|
|
|
@ -33,26 +33,25 @@
|
|||
* for getting information about and changing state of the APU.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <bakery_lock.h>
|
||||
#include <gicv2.h>
|
||||
#include <gic_common.h>
|
||||
#include <bl_common.h>
|
||||
#include <mmio.h>
|
||||
#include <string.h>
|
||||
#include <utils.h>
|
||||
#include "pm_api_sys.h"
|
||||
#include "pm_client.h"
|
||||
#include "pm_ipi.h"
|
||||
#include "../zynqmp_def.h"
|
||||
|
||||
#define OCM_BANK_0 0xFFFC0000
|
||||
#define OCM_BANK_1 (OCM_BANK_0 + 0x10000)
|
||||
#define OCM_BANK_2 (OCM_BANK_1 + 0x10000)
|
||||
#define OCM_BANK_3 (OCM_BANK_2 + 0x10000)
|
||||
|
||||
#define IRQ_MAX 84
|
||||
#define NUM_GICD_ISENABLER ((IRQ_MAX >> 5) + 1)
|
||||
#define UNDEFINED_CPUID (~0)
|
||||
|
||||
DEFINE_BAKERY_LOCK(pm_client_secure_lock);
|
||||
|
||||
/* Declaration of linker defined symbol */
|
||||
extern unsigned long __BL31_END__;
|
||||
extern const struct pm_ipi apu_ipi;
|
||||
|
||||
/* Order in pm_procs_all array must match cpu ids */
|
||||
|
@ -79,36 +78,146 @@ static const struct pm_proc const pm_procs_all[] = {
|
|||
},
|
||||
};
|
||||
|
||||
/* Interrupt to PM node ID map */
|
||||
static enum pm_node_id irq_node_map[IRQ_MAX + 1] = {
|
||||
NODE_UNKNOWN,
|
||||
NODE_UNKNOWN,
|
||||
NODE_UNKNOWN,
|
||||
NODE_UNKNOWN, /* 3 */
|
||||
NODE_UNKNOWN,
|
||||
NODE_UNKNOWN,
|
||||
NODE_UNKNOWN,
|
||||
NODE_UNKNOWN, /* 7 */
|
||||
NODE_UNKNOWN,
|
||||
NODE_UNKNOWN,
|
||||
NODE_UNKNOWN,
|
||||
NODE_UNKNOWN, /* 11 */
|
||||
NODE_UNKNOWN,
|
||||
NODE_UNKNOWN,
|
||||
NODE_NAND,
|
||||
NODE_QSPI, /* 15 */
|
||||
NODE_GPIO,
|
||||
NODE_I2C_0,
|
||||
NODE_I2C_1,
|
||||
NODE_SPI_0, /* 19 */
|
||||
NODE_SPI_1,
|
||||
NODE_UART_0,
|
||||
NODE_UART_1,
|
||||
NODE_CAN_0, /* 23 */
|
||||
NODE_CAN_1,
|
||||
NODE_UNKNOWN,
|
||||
NODE_RTC,
|
||||
NODE_RTC, /* 27 */
|
||||
NODE_UNKNOWN,
|
||||
NODE_UNKNOWN,
|
||||
NODE_UNKNOWN,
|
||||
NODE_UNKNOWN, /* 31 */
|
||||
NODE_UNKNOWN,
|
||||
NODE_UNKNOWN,
|
||||
NODE_UNKNOWN,
|
||||
NODE_UNKNOWN, /* 35, NODE_IPI_APU */
|
||||
NODE_TTC_0,
|
||||
NODE_TTC_0,
|
||||
NODE_TTC_0,
|
||||
NODE_TTC_1, /* 39 */
|
||||
NODE_TTC_1,
|
||||
NODE_TTC_1,
|
||||
NODE_TTC_2,
|
||||
NODE_TTC_2, /* 43 */
|
||||
NODE_TTC_2,
|
||||
NODE_TTC_3,
|
||||
NODE_TTC_3,
|
||||
NODE_TTC_3, /* 47 */
|
||||
NODE_SD_0,
|
||||
NODE_SD_1,
|
||||
NODE_SD_0,
|
||||
NODE_SD_1, /* 51 */
|
||||
NODE_UNKNOWN,
|
||||
NODE_UNKNOWN,
|
||||
NODE_UNKNOWN,
|
||||
NODE_UNKNOWN, /* 55 */
|
||||
NODE_UNKNOWN,
|
||||
NODE_ETH_0,
|
||||
NODE_ETH_0,
|
||||
NODE_ETH_1, /* 59 */
|
||||
NODE_ETH_1,
|
||||
NODE_ETH_2,
|
||||
NODE_ETH_2,
|
||||
NODE_ETH_3, /* 63 */
|
||||
NODE_ETH_3,
|
||||
NODE_USB_0,
|
||||
NODE_USB_0,
|
||||
NODE_USB_0, /* 67 */
|
||||
NODE_USB_0,
|
||||
NODE_USB_0,
|
||||
NODE_USB_1,
|
||||
NODE_USB_1, /* 71 */
|
||||
NODE_USB_1,
|
||||
NODE_USB_1,
|
||||
NODE_USB_1,
|
||||
NODE_USB_0, /* 75 */
|
||||
NODE_USB_0,
|
||||
NODE_ADMA,
|
||||
NODE_ADMA,
|
||||
NODE_ADMA, /* 79 */
|
||||
NODE_ADMA,
|
||||
NODE_ADMA,
|
||||
NODE_ADMA,
|
||||
NODE_ADMA, /* 83 */
|
||||
NODE_ADMA,
|
||||
};
|
||||
|
||||
/**
|
||||
* set_ocm_retention() - Configure OCM memory banks for retention
|
||||
* irq_to_pm_node - Get PM node ID corresponding to the interrupt number
|
||||
* @irq: Interrupt number
|
||||
*
|
||||
* APU specific requirements for suspend action:
|
||||
* OCM has to enter retention state in order to preserve saved
|
||||
* context after suspend request. OCM banks are determined by
|
||||
* __BL31_END__ linker symbol.
|
||||
*
|
||||
* Return: Returns status, either success or error+reason
|
||||
* Return: PM node ID corresponding to the specified interrupt
|
||||
*/
|
||||
enum pm_ret_status set_ocm_retention(void)
|
||||
static enum pm_node_id irq_to_pm_node(unsigned int irq)
|
||||
{
|
||||
enum pm_ret_status ret;
|
||||
assert(irq <= IRQ_MAX);
|
||||
return irq_node_map[irq];
|
||||
}
|
||||
|
||||
/* OCM_BANK_0 will always be occupied */
|
||||
ret = pm_set_requirement(NODE_OCM_BANK_0, PM_CAP_CONTEXT, 0,
|
||||
REQ_ACK_NO);
|
||||
/**
|
||||
* pm_client_set_wakeup_sources - Set all slaves with enabled interrupts as wake
|
||||
* sources in the PMU firmware
|
||||
*/
|
||||
static void pm_client_set_wakeup_sources(void)
|
||||
{
|
||||
uint32_t reg_num;
|
||||
uint8_t pm_wakeup_nodes_set[NODE_MAX];
|
||||
uintptr_t isenabler1 = BASE_GICD_BASE + GICD_ISENABLER + 4;
|
||||
|
||||
/* Check for other OCM banks */
|
||||
if ((unsigned long)&__BL31_END__ >= OCM_BANK_1)
|
||||
ret = pm_set_requirement(NODE_OCM_BANK_1, PM_CAP_CONTEXT, 0,
|
||||
REQ_ACK_NO);
|
||||
if ((unsigned long)&__BL31_END__ >= OCM_BANK_2)
|
||||
ret = pm_set_requirement(NODE_OCM_BANK_2, PM_CAP_CONTEXT, 0,
|
||||
REQ_ACK_NO);
|
||||
if ((unsigned long)&__BL31_END__ >= OCM_BANK_3)
|
||||
ret = pm_set_requirement(NODE_OCM_BANK_3, PM_CAP_CONTEXT, 0,
|
||||
REQ_ACK_NO);
|
||||
memset(&pm_wakeup_nodes_set, 0, sizeof(pm_wakeup_nodes_set));
|
||||
|
||||
return ret;
|
||||
for (reg_num = 0; reg_num < NUM_GICD_ISENABLER; reg_num++) {
|
||||
uint32_t base_irq = reg_num << ISENABLER_SHIFT;
|
||||
uint32_t reg = mmio_read_32(isenabler1 + (reg_num << 2));
|
||||
|
||||
if (!reg)
|
||||
continue;
|
||||
|
||||
while (reg) {
|
||||
enum pm_node_id node;
|
||||
uint32_t idx, ret, irq, lowest_set = reg & (-reg);
|
||||
|
||||
idx = __builtin_ctz(lowest_set);
|
||||
irq = base_irq + idx;
|
||||
|
||||
if (irq > IRQ_MAX)
|
||||
break;
|
||||
|
||||
node = irq_to_pm_node(irq);
|
||||
reg &= ~lowest_set;
|
||||
|
||||
if ((node != NODE_UNKNOWN) &&
|
||||
(!pm_wakeup_nodes_set[node])) {
|
||||
ret = pm_set_wakeup_source(NODE_APU, node, 1);
|
||||
pm_wakeup_nodes_set[node] = !ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -162,11 +271,15 @@ const struct pm_proc *primary_proc = &pm_procs_all[0];
|
|||
*
|
||||
* This function should contain any PU-specific actions
|
||||
* required prior to sending suspend request to PMU
|
||||
* Actions taken depend on the state system is suspending to.
|
||||
*/
|
||||
void pm_client_suspend(const struct pm_proc *proc)
|
||||
void pm_client_suspend(const struct pm_proc *proc, unsigned int state)
|
||||
{
|
||||
bakery_lock_get(&pm_client_secure_lock);
|
||||
|
||||
if (state == PM_STATE_SUSPEND_TO_RAM)
|
||||
pm_client_set_wakeup_sources();
|
||||
|
||||
/* Set powerdown request */
|
||||
mmio_write_32(APU_PWRCTL, mmio_read_32(APU_PWRCTL) | proc->pwrdn_mask);
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
#include "pm_common.h"
|
||||
|
||||
/* Functions to be implemented by each PU */
|
||||
void pm_client_suspend(const struct pm_proc *proc);
|
||||
void pm_client_suspend(const struct pm_proc *proc, unsigned int state);
|
||||
void pm_client_abort_suspend(void);
|
||||
void pm_client_wakeup(const struct pm_proc *proc);
|
||||
enum pm_ret_status set_ocm_retention(void);
|
||||
|
|
|
@ -53,6 +53,10 @@
|
|||
#define MAX_LATENCY (~0U)
|
||||
#define MAX_QOS 100U
|
||||
|
||||
/* State arguments of the self suspend */
|
||||
#define PM_STATE_CPU_IDLE 0x0U
|
||||
#define PM_STATE_SUSPEND_TO_RAM 0xFU
|
||||
|
||||
/*********************************************************************
|
||||
* Enum definitions
|
||||
********************************************************************/
|
||||
|
@ -82,6 +86,10 @@ enum pm_api_id {
|
|||
PM_RESET_GET_STATUS,
|
||||
PM_MMIO_WRITE,
|
||||
PM_MMIO_READ,
|
||||
PM_INIT,
|
||||
PM_FPGA_LOAD,
|
||||
PM_FPGA_GET_STATUS,
|
||||
PM_GET_CHIPID,
|
||||
PM_API_MAX
|
||||
};
|
||||
|
||||
|
@ -143,6 +151,12 @@ enum pm_node_id {
|
|||
NODE_IOPLL,
|
||||
NODE_DDR,
|
||||
NODE_IPI_APU,
|
||||
NODE_IPI_RPU_0,
|
||||
NODE_GPU,
|
||||
NODE_PCIE,
|
||||
NODE_PCAP,
|
||||
NODE_RTC,
|
||||
NODE_MAX
|
||||
};
|
||||
|
||||
enum pm_request_ack {
|
||||
|
|
|
@ -228,6 +228,22 @@ uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
|
|||
ret = pm_mmio_read(pm_arg[0], &value);
|
||||
SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32);
|
||||
}
|
||||
|
||||
case PM_FPGA_LOAD:
|
||||
ret = pm_fpga_load(pm_arg[0], pm_arg[1], pm_arg[2], pm_arg[3]);
|
||||
SMC_RET1(handle, (uint64_t)ret);
|
||||
|
||||
case PM_FPGA_GET_STATUS:
|
||||
{
|
||||
uint32_t value;
|
||||
|
||||
ret = pm_fpga_get_status(&value);
|
||||
SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32);
|
||||
}
|
||||
|
||||
case PM_GET_CHIPID:
|
||||
SMC_RET1(handle, zynqmp_get_silicon_id());
|
||||
|
||||
default:
|
||||
WARN("Unimplemented PM Service Call: 0x%x\n", smc_fid);
|
||||
SMC_RET1(handle, SMC_UNK);
|
||||
|
|
|
@ -201,4 +201,8 @@
|
|||
|
||||
#define ZYNQMP_CSU_VERSION_OFFSET 0x44
|
||||
|
||||
/* Access control register defines */
|
||||
#define ACTLR_EL3_L2ACTLR_BIT (1 << 6)
|
||||
#define ACTLR_EL3_CPUACTLR_BIT (1 << 0)
|
||||
|
||||
#endif /* __ZYNQMP_DEF_H__ */
|
||||
|
|
|
@ -39,6 +39,7 @@ void zynqmp_config_setup(void);
|
|||
unsigned int zynqmp_get_uart_clk(void);
|
||||
int zynqmp_is_pmu_up(void);
|
||||
unsigned int zynqmp_get_bootmode(void);
|
||||
unsigned int zynqmp_get_silicon_id(void);
|
||||
|
||||
/* For FSBL handover */
|
||||
void fsbl_atf_handover(entry_point_info_t *bl32_image_ep_info,
|
||||
|
|
Loading…
Reference in New Issue