1 /*
2  * Arm SCP/MCP Software
3  * Copyright (c) 2019-2022, Arm Limited and Contributors. All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #ifndef CLOCK_H
9 #define CLOCK_H
10 
11 #include <mod_clock.h>
12 
13 #include <fwk_event.h>
14 #include <fwk_id.h>
15 #include <fwk_list.h>
16 
17 /* Device context */
18 struct clock_dev_ctx {
19     /* Pointer to the element configuration data */
20     const struct mod_clock_dev_config *config;
21 
22     /* Driver API */
23     struct mod_clock_drv_api *api;
24 
25     struct {
26         /* Cookie for the pre-transition notification response */
27         unsigned int pre_power_transition_cookie;
28 
29         /* Counter of notifications sent */
30         unsigned int transition_pending_sent;
31 
32         /* Status of the pending transition */
33         unsigned int transition_pending_response_status;
34     } pd_notif;
35 
36     struct {
37         /* A request is on-going */
38         bool is_ongoing;
39 
40         /* Cookie for the response event */
41         uint32_t cookie;
42     } request;
43 
44 #ifdef BUILD_HAS_CLOCK_TREE_MGMT
45     /* Identifier of the clock */
46     fwk_id_t id;
47 
48     /* Parent identifier */
49     fwk_id_t parent_id;
50 
51     /* List all clock children if any */
52     struct fwk_slist children_list;
53 
54     /*
55      * Node in the parent list if not the root
56      */
57     struct fwk_slist_node child_node;
58 
59     /* Clock state transition */
60     struct {
61         /* Number of pending responses */
62         uint32_t pending_responses;
63         /* Clock state transition */
64         uint32_t state;
65         /* Clock id caller to transition */
66         fwk_id_t caller_id;
67         /* Flag indicating if this clock is the starter of transition */
68         bool is_transition_initiator;
69     } state_transition;
70 
71     /* Reference count */
72     uint32_t ref_count;
73 #endif
74 };
75 
76 /* Module context */
77 struct clock_ctx {
78     /* Pointer to the module configuration data */
79     const struct mod_clock_config *config;
80 
81     /* Table of elements context */
82     struct clock_dev_ctx *dev_ctx_table;
83 
84     /* Number of clocks devices */
85     uint32_t dev_count;
86 };
87 
88 /* Set state event parameters */
89 struct clock_set_state_params {
90     uint32_t target_state;
91     int caller_status;
92 };
93 
94 /* Set rate event parameters */
95 struct clock_set_rate_params {
96     uint64_t input_rate;
97 };
98 
99 /* List of state transition management state */
100 enum clock_state_transition_stage {
101     /* This is the idle state */
102     CLOCK_STATE_TRANSITION_IDLE,
103 
104     /* This state wait for parent run response */
105     CLOCK_STATE_TRANSITION_WAIT_PARENT,
106 
107     /* Number of states in a transition */
108     CLOCK_STATE_TRANSITION_COUNT
109 };
110 
111 /* Get context helper function */
112 void clock_get_ctx(fwk_id_t clock_id, struct clock_dev_ctx **ctx);
113 
114 /* Clock request complete function */
115 void clock_request_complete(
116     fwk_id_t dev_id,
117     struct mod_clock_driver_resp_params *response);
118 
119 #ifdef BUILD_HAS_CLOCK_TREE_MGMT
120 /* Clock tree management state machine for setting state */
121 int clock_management_process_state(const struct fwk_event *event);
122 
123 /* Clock tree management state machine for setting rate */
124 int clock_management_process_rate(const struct fwk_event *event);
125 
126 /* Check if a clock is a single node. It returns true or false whether Clock is
127  * a single node or not.
128  */
129 bool clock_is_single_node(struct clock_dev_ctx *ctx);
130 
131 /* Connect clock tree interconnecting parent to children nodes */
132 int clock_connect_tree(struct clock_ctx *module_ctx);
133 #endif
134 
135 /*
136  * Clock event indexes.
137  */
138 enum clock_event_idx {
139     CLOCK_EVENT_IDX_RESPONSE = MOD_CLOCK_EVENT_IDX_COUNT,
140 
141 #ifdef BUILD_HAS_CLOCK_TREE_MGMT
142     CLOCK_EVENT_IDX_SET_STATE_PRE_REQUEST,
143     CLOCK_EVENT_IDX_SET_RATE_PRE_REQUEST,
144 #endif
145 
146     CLOCK_EVENT_IDX_COUNT
147 };
148 
149 /*
150  * Event identifiers.
151  */
152 
153 /* Identifier of the response event */
154 static const fwk_id_t mod_clock_event_id_response =
155     FWK_ID_EVENT_INIT(FWK_MODULE_IDX_CLOCK, CLOCK_EVENT_IDX_RESPONSE);
156 
157 #ifdef BUILD_HAS_CLOCK_TREE_MGMT
158 /* Identifier of the set state pre-request */
159 static const fwk_id_t mod_clock_event_id_set_state_pre_request =
160     FWK_ID_EVENT_INIT(
161         FWK_MODULE_IDX_CLOCK,
162         CLOCK_EVENT_IDX_SET_STATE_PRE_REQUEST);
163 
164 /* Identifier of the set rate pre-request */
165 static const fwk_id_t mod_clock_event_id_set_rate_pre_request =
166     FWK_ID_EVENT_INIT(
167         FWK_MODULE_IDX_CLOCK,
168         CLOCK_EVENT_IDX_SET_RATE_PRE_REQUEST);
169 #endif
170 
171 #endif /* CLOCK_H */
172