1c73a90e5STejas Patel /* 2c73a90e5STejas Patel * Copyright (c) 2019, Xilinx, Inc. All rights reserved. 3c73a90e5STejas Patel * 4c73a90e5STejas Patel * SPDX-License-Identifier: BSD-3-Clause 5c73a90e5STejas Patel */ 6c73a90e5STejas Patel 7c73a90e5STejas Patel /* 8c73a90e5STejas Patel * APU specific definition of processors in the subsystem as well as functions 9c73a90e5STejas Patel * for getting information about and changing state of the APU. 10c73a90e5STejas Patel */ 11c73a90e5STejas Patel 12c73a90e5STejas Patel #include <plat_ipi.h> 13c73a90e5STejas Patel #include <platform_def.h> 14c73a90e5STejas Patel #include <versal_def.h> 15c73a90e5STejas Patel #include <lib/bakery_lock.h> 16*fbb32695STejas Patel #include <lib/mmio.h> 17*fbb32695STejas Patel #include <drivers/arm/gicv3.h> 18*fbb32695STejas Patel #include <plat/common/platform.h> 19c73a90e5STejas Patel #include "pm_client.h" 20c73a90e5STejas Patel 21c73a90e5STejas Patel DEFINE_BAKERY_LOCK(pm_client_secure_lock); 22c73a90e5STejas Patel 23c73a90e5STejas Patel static const struct pm_ipi apu_ipi = { 24c73a90e5STejas Patel .local_ipi_id = IPI_ID_APU, 25c73a90e5STejas Patel .remote_ipi_id = IPI_ID_PMC, 26c73a90e5STejas Patel .buffer_base = IPI_BUFFER_APU_BASE, 27c73a90e5STejas Patel }; 28c73a90e5STejas Patel 29c73a90e5STejas Patel /* Order in pm_procs_all array must match cpu ids */ 30c73a90e5STejas Patel static const struct pm_proc pm_procs_all[] = { 31c73a90e5STejas Patel { 32c73a90e5STejas Patel .node_id = XPM_DEVID_ACPU_0, 33c73a90e5STejas Patel .ipi = &apu_ipi, 34*fbb32695STejas Patel .pwrdn_mask = APU_0_PWRCTL_CPUPWRDWNREQ_MASK, 35c73a90e5STejas Patel }, 36c73a90e5STejas Patel { 37c73a90e5STejas Patel .node_id = XPM_DEVID_ACPU_1, 38c73a90e5STejas Patel .ipi = &apu_ipi, 39*fbb32695STejas Patel .pwrdn_mask = APU_1_PWRCTL_CPUPWRDWNREQ_MASK, 40c73a90e5STejas Patel } 41c73a90e5STejas Patel }; 42c73a90e5STejas Patel 43c73a90e5STejas Patel const struct pm_proc *primary_proc = &pm_procs_all[0]; 44*fbb32695STejas Patel 45*fbb32695STejas Patel /** 46*fbb32695STejas Patel * pm_client_suspend() - Client-specific suspend actions 47*fbb32695STejas Patel * 48*fbb32695STejas Patel * This function should contain any PU-specific actions 49*fbb32695STejas Patel * required prior to sending suspend request to PMU 50*fbb32695STejas Patel * Actions taken depend on the state system is suspending to. 51*fbb32695STejas Patel */ 52*fbb32695STejas Patel void pm_client_suspend(const struct pm_proc *proc, unsigned int state) 53*fbb32695STejas Patel { 54*fbb32695STejas Patel bakery_lock_get(&pm_client_secure_lock); 55*fbb32695STejas Patel 56*fbb32695STejas Patel /* Set powerdown request */ 57*fbb32695STejas Patel mmio_write_32(FPD_APU_PWRCTL, mmio_read_32(FPD_APU_PWRCTL) | 58*fbb32695STejas Patel proc->pwrdn_mask); 59*fbb32695STejas Patel 60*fbb32695STejas Patel bakery_lock_release(&pm_client_secure_lock); 61*fbb32695STejas Patel } 62*fbb32695STejas Patel 63*fbb32695STejas Patel /** 64*fbb32695STejas Patel * pm_client_abort_suspend() - Client-specific abort-suspend actions 65*fbb32695STejas Patel * 66*fbb32695STejas Patel * This function should contain any PU-specific actions 67*fbb32695STejas Patel * required for aborting a prior suspend request 68*fbb32695STejas Patel */ 69*fbb32695STejas Patel void pm_client_abort_suspend(void) 70*fbb32695STejas Patel { 71*fbb32695STejas Patel /* Enable interrupts at processor level (for current cpu) */ 72*fbb32695STejas Patel gicv3_cpuif_enable(plat_my_core_pos()); 73*fbb32695STejas Patel 74*fbb32695STejas Patel bakery_lock_get(&pm_client_secure_lock); 75*fbb32695STejas Patel 76*fbb32695STejas Patel /* Clear powerdown request */ 77*fbb32695STejas Patel mmio_write_32(FPD_APU_PWRCTL, mmio_read_32(FPD_APU_PWRCTL) & 78*fbb32695STejas Patel ~primary_proc->pwrdn_mask); 79*fbb32695STejas Patel 80*fbb32695STejas Patel bakery_lock_release(&pm_client_secure_lock); 81*fbb32695STejas Patel } 82*fbb32695STejas Patel 83*fbb32695STejas Patel /** 84*fbb32695STejas Patel * pm_get_proc() - returns pointer to the proc structure 85*fbb32695STejas Patel * @cpuid: id of the cpu whose proc struct pointer should be returned 86*fbb32695STejas Patel * 87*fbb32695STejas Patel * Return: pointer to a proc structure if proc is found, otherwise NULL 88*fbb32695STejas Patel */ 89*fbb32695STejas Patel const struct pm_proc *pm_get_proc(unsigned int cpuid) 90*fbb32695STejas Patel { 91*fbb32695STejas Patel if (cpuid < ARRAY_SIZE(pm_procs_all)) 92*fbb32695STejas Patel return &pm_procs_all[cpuid]; 93*fbb32695STejas Patel 94*fbb32695STejas Patel return NULL; 95*fbb32695STejas Patel } 96