/** * pm_req_wakeup() - PM call for processor to wake up selected processor * or subsystem * @target Node id of the processor or subsystem to wake up * @ack Flag to specify whether acknowledge requested * @set_address Resume address presence indicator * 1 resume address specified, 0 otherwise * @address Resume address * * This API function is either used to power up another APU core for SMP * (by PSCI) or to power up an entirely different PU or subsystem, such * as RPU0, RPU, or PL_CORE_xx. Resume address for the target PU will be * automatically set by PMU. * * @return Returns status, either success or error+reason */ enum pm_ret_status pm_req_wakeup(enum pm_node_id target, unsigned int set_address, uintptr_t address, enum pm_request_ack ack) { uint32_t payload[PAYLOAD_ARG_CNT]; uint64_t encoded_address; const struct pm_proc *proc = pm_get_proc_by_node(target); /* invoke APU-specific code for waking up another APU core */ pm_client_wakeup(proc); /* encode set Address into 1st bit of address */ encoded_address = address; encoded_address |= !!set_address; /* Send request to the PMU to perform the wake of the PU */ PM_PACK_PAYLOAD5(payload, PM_REQ_WAKEUP, target, encoded_address, encoded_address >> 32, ack); if (ack == REQ_ACK_BLOCKING) return pm_ipi_send_sync(primary_proc, payload, NULL); else return pm_ipi_send(primary_proc, payload); }
static void zynqmp_pwr_domain_suspend_finish(const psci_power_state_t *target_state) { unsigned int cpu_id = plat_my_core_pos(); const struct pm_proc *proc = pm_get_proc(cpu_id); for (size_t i = 0; i <= PLAT_MAX_PWR_LVL; i++) VERBOSE("%s: target_state->pwr_domain_state[%lu]=%x\n", __func__, i, target_state->pwr_domain_state[i]); /* Clear the APU power control register for this cpu */ pm_client_wakeup(proc); /* enable coherency */ plat_arm_interconnect_enter_coherency(); }
static int zynqmp_pwr_domain_on(u_register_t mpidr) { unsigned int cpu_id = plat_core_pos_by_mpidr(mpidr); const struct pm_proc *proc; VERBOSE("%s: mpidr: 0x%lx\n", __func__, mpidr); if (cpu_id == -1) return PSCI_E_INTERN_FAIL; proc = pm_get_proc(cpu_id); /* Clear power down request */ pm_client_wakeup(proc); /* Send request to PMU to wake up selected APU CPU core */ pm_req_wakeup(proc->node_id, 1, zynqmp_sec_entry, REQ_ACK_BLOCKING); return PSCI_E_SUCCESS; }