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