1 /*
2  * Arm SCP/MCP Software
3  * Copyright (c) 2015-2021, Arm Limited and Contributors. All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  *
7  * Description:
8  *     PPU v1 Driver
9  */
10 
11 #ifndef MOD_PPU_V1_H
12 #define MOD_PPU_V1_H
13 
14 #include <mod_power_domain.h>
15 
16 #include <fwk_id.h>
17 
18 #include <stdbool.h>
19 #include <stddef.h>
20 #include <stdint.h>
21 
22 /*!
23  * \addtogroup GroupModules Modules
24  * \{
25  */
26 
27 /*!
28  * \defgroup GroupModulePPUv1 PPUv1 Driver
29  * \{
30  */
31 
32 /*!
33  * \brief Indexes of the interfaces exposed by the module.
34  */
35 enum mod_ppu_v1_api_idx {
36     /*! Power domain driver API */
37     MOD_PPU_V1_API_IDX_POWER_DOMAIN_DRIVER,
38     /*! interrupt Service Routine driver API */
39     MOD_PPU_V1_API_IDX_ISR,
40     /*! System boot API */
41     MOD_PPU_V1_API_IDX_BOOT,
42     /*! Number of exposed interfaces */
43     MOD_PPU_V1_API_IDX_COUNT,
44 };
45 
46 /*!
47  * \brief PPU_V1 OPERATING MODES
48  */
49 enum ppu_v1_opmode {
50     PPU_V1_OPMODE_00,
51     PPU_V1_OPMODE_01,
52     PPU_V1_OPMODE_02,
53     PPU_V1_OPMODE_03,
54     PPU_V1_OPMODE_04,
55     PPU_V1_OPMODE_05,
56     PPU_V1_OPMODE_06,
57     PPU_V1_OPMODE_07,
58     PPU_V1_OPMODE_08,
59     PPU_V1_OPMODE_09,
60     PPU_V1_OPMODE_10,
61     PPU_V1_OPMODE_11,
62     PPU_V1_OPMODE_12,
63     PPU_V1_OPMODE_13,
64     PPU_V1_OPMODE_14,
65     PPU_V1_OPMODE_15,
66     /* No valid operating modes after this line */
67     PPU_V1_OPMODE_COUNT
68 };
69 
70 /*!
71  * \brief Power domain PPU descriptor.
72  */
73 struct mod_ppu_v1 {
74     /*! Base address of the PPU registers */
75     uintptr_t reg_base;
76 
77     /*! PPU's IRQ number */
78     unsigned int irq;
79 };
80 /*!
81  * \brief Timer for set_state.
82  *
83  * \details This structure is required to be filled in PPUv1 config file only
84  *          when the timeout feature is required.
85  */
86 struct mod_ppu_v1_timer_config {
87     /*!
88      * \brief Timer identifier.
89      *
90      * \details Used for binding with the timer API and waiting for specified
91      *          delay after setting the PPU state.
92      */
93     fwk_id_t timer_id;
94 
95     /*!
96      * PPU state change wait delay in micro seconds.
97      * A valid non-zero value has to be specified when using this feature.
98      */
99     uint32_t set_state_timeout_us;
100 };
101 
102 /*!
103  * \brief PPU_V1 module configuration
104  */
105 struct mod_ppu_v1_config {
106     /*! Identifier of the power domain notification to register elements for */
107     const fwk_id_t pd_notification_id;
108 
109     /*!
110      * Identifier of the source module or element that is expected to send power
111      * domain notifications.
112      */
113     fwk_id_t pd_source_id;
114 };
115 
116 /*!
117  * \brief Configuration data of a power domain of the PPU_V1 driver module.
118  */
119 struct mod_ppu_v1_pd_config {
120     /*! Power domain type */
121     enum mod_pd_type pd_type;
122 
123     /*! PPU descriptor */
124     struct mod_ppu_v1 ppu;
125 
126     /*!
127      *  In the case of a core power domain, identifier of the cluster power
128      *  domain it belongs to. If the power domain is not a core power domain,
129      *  the value of this field is undefined.
130      */
131     fwk_id_t cluster_id;
132 
133     /*!
134      *  Product specific ppu opmode.
135      */
136     enum ppu_v1_opmode opmode;
137 
138     /*!
139      * Flag indicating if this domain should be powered on during element
140      * init. This flag is only supported for device and system PPUs and should
141      * not be set for any other type. Timeout is not provided at this stage.
142      */
143     bool default_power_on;
144 
145     /*!
146      * \brief Identifier of an entity wishing to be notified when the PPU
147      *     transitions out of the OFF state.
148      *
149      * \note This field may be set to ::FWK_ID_NONE, in which case no
150      *     observer will be set.
151      */
152     fwk_id_t observer_id;
153 
154     /*!
155      * \brief Identifier of the power state observer API implemented by
156      *     ::mod_ppu_v1_pd_config::observer_id.
157      */
158     fwk_id_t observer_api;
159 
160     /*!
161      * \brief Parameter passed to
162      *     ::mod_ppu_v1_power_state_observer_api::post_ppu_on().
163      */
164     void *post_ppu_on_param;
165 
166     /*! Timer descriptor */
167     struct mod_ppu_v1_timer_config *timer_config;
168 };
169 
170 /*!
171  * \brief PPU_V1 Power State Observer API.
172  *
173  * \details This API should be implemented by any modules that should be
174  *     notified when a PPU changes state.
175  */
176 struct mod_ppu_v1_power_state_observer_api {
177     /*!
178      * \brief Called after a PPU has turned on.
179      *
180      * \param param Generic configurable parameter.
181      */
182     void (*post_ppu_on)(void *param);
183 };
184 
185 /*!
186  * \brief PPU_V1 module ISR API
187  */
188 struct ppu_v1_isr_api {
189     /*!
190      * \brief Handle a power domain PPU interrupt
191      *
192      * \param pd_id Identifier of the power domain
193      */
194     void (*ppu_interrupt_handler)(fwk_id_t pd_id);
195 };
196 
197 /*!
198  * \brief PPU_V1 module boot API
199  */
200 struct ppu_v1_boot_api {
201     /*!
202      * \brief Power on a specified power domain
203      *
204      * \param pd_id Identifier of the power domain
205      *
206      * \retval ::FWK_SUCCESS Operation successful.
207      * \return One of the standard framework error codes.
208      */
209     int (*power_mode_on)(fwk_id_t pd_id);
210 };
211 
212 /*!
213  * \}
214  */
215 
216 /*!
217  * \}
218  */
219 
220 #endif /* MOD_PPU_V1_H */
221